112 lines
2.1 KiB
C
112 lines
2.1 KiB
C
#include "axl.h"
|
|
|
|
static uint8_t memory[AXL_HEAP_SIZE];
|
|
|
|
struct mb_header
|
|
{
|
|
uint32_t size;
|
|
bool 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, int8_t c, int32_t n)
|
|
{
|
|
if(ptr)
|
|
{
|
|
for(int32_t i = 0; i < n; i++)
|
|
{
|
|
((int8_t*)ptr)[i] = c;
|
|
}
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
|
|
void axl_init(void)
|
|
{
|
|
static bool 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(uint32_t 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, uint32_t size)
|
|
{
|
|
if(block->size > size + MB_HEADER_SIZE)
|
|
{
|
|
mb_header* new_block = (mb_header*)((uint8_t*)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(uint32_t 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*)((uint8_t*)free_block + MB_HEADER_SIZE);
|
|
}
|
|
|
|
void axl_free(void* ptr)
|
|
{
|
|
if(!ptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
mb_header* block = (mb_header*)((uint8_t*)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;
|
|
}
|
|
}
|