diff --git a/include/memory.h b/include/memory.h index 19536fd..23b5f53 100644 --- a/include/memory.h +++ b/include/memory.h @@ -1,8 +1,10 @@ #pragma once +#include "stdint.h" + #define NULL ((void*)0) void heap_init(); -void* malloc(); +void* malloc(size_t size); void free(void* ptr); \ No newline at end of file diff --git a/src/convert.c b/src/convert.c index 3a94342..503752c 100644 --- a/src/convert.c +++ b/src/convert.c @@ -30,7 +30,7 @@ char* ultoa(unsigned long number, char* string, int base) return string; } - char* buffer = (char*)malloc(); + char* buffer = (char*)malloc(1024); char* temp = buffer; int i = 0; diff --git a/src/memory.c b/src/memory.c index f3895e8..5955afd 100644 --- a/src/memory.c +++ b/src/memory.c @@ -1,14 +1,20 @@ #include "memory.h" -#include "stdint.h" #include "io.h" #include "convert.h" struct FreeBlock { + size_t size; struct FreeBlock* next; }; +struct Block +{ + size_t size; + void* data; +}; + #define HEAP_BASE ((void*)0x40000000) #define BLOCK_SIZE 4096 #define MAGIC_NUMBER 0xDEADBEEF @@ -17,54 +23,60 @@ static struct FreeBlock* head = (struct FreeBlock*)HEAP_BASE; void heap_init() { - head->next = NULL; + head->next = head + sizeof(struct FreeBlock); + head->size = 0; + + head->next->next = NULL; + head->next->size = -1; } -void* malloc() +struct FreeBlock* find_free_block(struct FreeBlock** previous, size_t min_size) { - void* block = (void*)head; - - if(head->next == NULL) + struct FreeBlock* block = head; + while(block && min_size < block->size) { - head += BLOCK_SIZE; - head->next = NULL; + *previous = block; + block = block->next; + } + + return block; +} + +void* malloc(size_t size) +{ + size_t physicalSize = size + sizeof(size_t); + struct Block* allocation = NULL; + + struct FreeBlock* previous = head; + struct FreeBlock* block = find_free_block(&previous, physicalSize); + + allocation = (struct Block*)block; + allocation->size = size; + + if(block->size == physicalSize) + { + previous->next = block->next; } else { - head = head->next; + struct FreeBlock* shrunkBlock = block + physicalSize; + shrunkBlock->next = block->next; + shrunkBlock->size = shrunkBlock->next - shrunkBlock; + + previous->next = shrunkBlock; } - *(uint32_t*)block = MAGIC_NUMBER; - return block + sizeof(uint32_t); + return &(allocation->data); } void free(void* ptr) { - void* blockStart = ptr - sizeof(uint32_t); - if(*(uint32_t*)blockStart != MAGIC_NUMBER) - return; + struct FreeBlock* block = (struct FreeBlock*)((size_t*)ptr - 1); + + struct FreeBlock* previous = head; + while(previous && (void*)previous->next < ptr) + previous = previous->next; - if((struct FreeBlock*)blockStart < head) - { - struct FreeBlock* nextBlock = head->next; - head = blockStart; - head->next = nextBlock; - return; - } - - struct FreeBlock* block = head; - - while(block) - { - if(block < (struct FreeBlock*)blockStart && (struct FreeBlock*)blockStart < block->next) - { - struct FreeBlock* newBlock = (struct FreeBlock*)blockStart; - newBlock->next = block->next; - block->next = newBlock; - - return; - } - - block = block->next; - } + previous->next = block; + block->next = previous; } \ No newline at end of file