From 14d1667424f5afd21ead55f9540cb62feb41063a Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Wed, 3 Sep 2025 00:14:08 +0200 Subject: [PATCH] Free list allocator (rough) --- free_list.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 free_list.c diff --git a/free_list.c b/free_list.c new file mode 100644 index 0000000..3f3248b --- /dev/null +++ b/free_list.c @@ -0,0 +1,107 @@ +#include "stddef.h" +#include "stdint.h" +#include +#include +#include + +/* Free list allocator, unfinished code that i found laying around */ + +// extern uint8_t _heap_start; +// extern uint8_t _heap_end; + +#define HEAP_SIZE 1024 +static uint8_t heap_area[HEAP_SIZE]; + +typedef struct Block { + size_t size; + struct Block *next; + struct Block *prev; + uint8_t is_free; + uint8_t padding[3]; // To align to 8 bytes +} Block; + +#define ALIGNMENT 8 +#define ALIGN(size) (((size) + (ALIGNMENT - 1)) & ~(ALIGNMENT - 1)) + +static Block *free_list = NULL; + +static inline void fl_heap_init(void *heap_start, void *heap_end) { + free_list = (Block *)heap_start; + free_list->size = (size_t)((uint8_t *)heap_end - (uint8_t *)heap_start) - sizeof(Block); + free_list->next = NULL; + free_list->prev = NULL; + free_list->is_free = 1; +} + +static inline void *fl_malloc(size_t size) { + size = ALIGN(size); + Block *current = free_list; + + while (current) { + if (current->is_free && current->size >= size) { + if (current->size >= size + sizeof(Block) + ALIGNMENT) { + // Split + Block *new_block = (Block *)((uint8_t *)current + sizeof(Block) + size); + new_block->size = current->size - size - sizeof(Block); + new_block->next = current->next; + new_block->prev = current; + new_block->is_free = 1; + if (new_block->next) + new_block->next->prev = new_block; + + current->next = new_block; + current->size = size; + } + current->is_free = 0; + return (void *)((uint8_t *)current + sizeof(Block)); + } + current = current->next; + } + return NULL; // No suitable block +} + +void fl_free(void *ptr) { + if (!ptr) + return; + + /* The actual block struct resides _before_ the payload part */ + Block *block = (Block *)((uint8_t *)ptr - sizeof(Block)); + + /* Zero out the block payload to catch dangling pointers and such */ + memset(ptr, 0, block->size); + block->is_free = 1; + + /* Coalesce with next */ + if (block->next && block->next->is_free) { + block->size += sizeof(Block) + block->next->size; + block->next = block->next->next; + if (block->next) + block->next->prev = block; + } + + /* Coalesce with prev */ + if (block->prev && block->prev->is_free) { + block->prev->size += sizeof(Block) + block->size; + block->prev->next = block->next; + if (block->next) + block->next->prev = block->prev; + } + + ptr = NULL; +} + +int main(void) { + fl_heap_init(heap_area, heap_area + HEAP_SIZE); + + int *a = fl_malloc(sizeof(int)); + assert(a != NULL); + *a = 10; + + printf("a = %d\n", *a); + + fl_free(a); + printf("a = %d\n", *a); + printf("All good!\n"); + + return 0; +}