#include "axl_memory.h" static u8 memory[AXL_HEAP_SIZE]; struct mb_header { u32 size; b8 is_free; struct mb_header* next; }; typedef struct mb_header mb_header; #define MB_HEADER_SIZE sizeof(mb_header) static mb_header* root = 0; void* axl_memset(void* ptr, i8 c, u32 n) { if(ptr) { for(u32 i = 0; i < n; i++) { ((i8*)ptr)[i] = c; } } return ptr; } void axl_init(void) { static b8 axl_initialized = false; if(!axl_initialized) { axl_memset(memory, 0, AXL_HEAP_SIZE); root = (mb_header*)memory; root->is_free = true; root->next = NULL; root->size = AXL_HEAP_SIZE - MB_HEADER_SIZE; axl_initialized = true; } } mb_header* axl_find_mb(u32 req_size) { mb_header* block = root; while(block != NULL) { if(block->is_free && block->size >= req_size) { return block; } block = block->next; } return NULL; } void axl_split_mb(mb_header* block, u32 size) { if(block->size > size + MB_HEADER_SIZE) { mb_header* new_block = (mb_header*)((u8*)block + MB_HEADER_SIZE + size); new_block->size = block->size - size - MB_HEADER_SIZE; new_block->is_free = true; new_block->next = block->next; block->size = size; block->next = new_block; } } void* axl_malloc(u32 size) { if(size > AXL_HEAP_SIZE - MB_HEADER_SIZE) { return NULL; } mb_header* free_block = axl_find_mb(size); if(!free_block) { return NULL; } axl_split_mb(free_block, size); free_block->is_free = false; return (void*)((u8*)free_block + MB_HEADER_SIZE); } void axl_free(void* ptr) { if(!ptr) { return; } mb_header* block = (mb_header*)((u8*)ptr - MB_HEADER_SIZE); mb_header* next_block = block->next; block->is_free = true; if(next_block != NULL && next_block->is_free) { block->size += next_block->size + MB_HEADER_SIZE; block->next = next_block->next; } }