Use handles instead of self-pointers
This commit is contained in:
parent
ccec181771
commit
2f31564ce2
1 changed files with 53 additions and 25 deletions
78
axl_memory.c
78
axl_memory.c
|
|
@ -2,18 +2,31 @@
|
||||||
|
|
||||||
static u8 memory[AXL_HEAP_SIZE];
|
static u8 memory[AXL_HEAP_SIZE];
|
||||||
|
|
||||||
|
#if AXL_HEAP_SIZE <= 0xFF - 1
|
||||||
|
typedef u8 mb_handle;
|
||||||
|
#define AXL_INVALID_MB_HANDLE 0xFF
|
||||||
|
#elif AXL_HEAP_SIZE <= 0xFFFF - 1
|
||||||
|
typedef u16 mb_handle;
|
||||||
|
#define AXL_INVALID_MB_HANDLE 0xFFFF
|
||||||
|
#elif AXL_HEAP_SIZE <= 0xFFFFFFFF - 1
|
||||||
|
typedef u32 mb_handle;
|
||||||
|
#define AXL_INVALID_MB_HANDLE 0xFFFFFFFF
|
||||||
|
#else
|
||||||
|
#error UNSUPPORTED HEAP SIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct mb_header mb_header;
|
typedef struct mb_header mb_header;
|
||||||
|
|
||||||
struct mb_header
|
struct mb_header
|
||||||
{
|
{
|
||||||
u32 size;
|
u32 size;
|
||||||
b8 is_free;
|
b8 is_free;
|
||||||
mb_header* prev;
|
mb_handle prev;
|
||||||
mb_header* next;
|
mb_handle next;
|
||||||
};
|
};
|
||||||
|
|
||||||
static mb_header* root = NULL;
|
static mb_handle root_handle = 0;
|
||||||
static mb_header* nomad = NULL;
|
static mb_handle nomad_handle = 0;
|
||||||
|
|
||||||
#define AXL_ALIGNMENT 8
|
#define AXL_ALIGNMENT 8
|
||||||
|
|
||||||
|
|
@ -22,6 +35,21 @@ static inline u32 axl_align(u32 size)
|
||||||
return (size + (AXL_ALIGNMENT - 1)) & ~(AXL_ALIGNMENT - 1);
|
return (size + (AXL_ALIGNMENT - 1)) & ~(AXL_ALIGNMENT - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mb_header* axl_id_to_mb(mb_handle id)
|
||||||
|
{
|
||||||
|
if(id == AXL_INVALID_MB_HANDLE)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (mb_header*)&memory[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
static mb_handle axl_ptr_to_id(mb_header* ptr)
|
||||||
|
{
|
||||||
|
return (mb_handle)((u8*)ptr - memory);
|
||||||
|
}
|
||||||
|
|
||||||
#define MB_HEADER_SIZE axl_align(sizeof(mb_header))
|
#define MB_HEADER_SIZE axl_align(sizeof(mb_header))
|
||||||
|
|
||||||
void* axl_memset(void* ptr, i8 c, u32 n)
|
void* axl_memset(void* ptr, i8 c, u32 n)
|
||||||
|
|
@ -44,23 +72,23 @@ void axl_init(void)
|
||||||
if(!axl_initialized)
|
if(!axl_initialized)
|
||||||
{
|
{
|
||||||
axl_memset(memory, 0, AXL_HEAP_SIZE);
|
axl_memset(memory, 0, AXL_HEAP_SIZE);
|
||||||
root = (mb_header*)memory;
|
mb_header* root = axl_id_to_mb(root_handle);
|
||||||
root->is_free = true;
|
root->is_free = true;
|
||||||
root->next = NULL;
|
root->next = AXL_INVALID_MB_HANDLE;
|
||||||
root->prev = NULL;
|
root->prev = AXL_INVALID_MB_HANDLE;
|
||||||
root->size = AXL_HEAP_SIZE - MB_HEADER_SIZE;
|
root->size = AXL_HEAP_SIZE - MB_HEADER_SIZE;
|
||||||
axl_initialized = true;
|
axl_initialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline mb_header* axl_get_mb_header(void* ptr)
|
static inline mb_header* axl_ptr_to_mb(void* ptr)
|
||||||
{
|
{
|
||||||
return (mb_header*)((u8*)ptr - MB_HEADER_SIZE);
|
return (mb_header*)((u8*)ptr - MB_HEADER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static mb_header* axl_find_mb(u32 req_size)
|
static mb_header* axl_find_mb(u32 req_size)
|
||||||
{
|
{
|
||||||
mb_header* block = nomad ? nomad : root;
|
mb_header* block = nomad_handle ? axl_id_to_mb(nomad_handle) : axl_id_to_mb(root_handle);
|
||||||
mb_header* start = block;
|
mb_header* start = block;
|
||||||
|
|
||||||
while(block)
|
while(block)
|
||||||
|
|
@ -70,12 +98,12 @@ static mb_header* axl_find_mb(u32 req_size)
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
block = block->next;
|
block = axl_id_to_mb(block->next);
|
||||||
|
|
||||||
if(!block)
|
if(!block)
|
||||||
{
|
{
|
||||||
//nomad pointer didn't help us, start from root
|
//nomad pointer didn't help us, start from root
|
||||||
block = root;
|
block = axl_id_to_mb(root_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(block == start)
|
if(block == start)
|
||||||
|
|
@ -98,15 +126,15 @@ static b8 axl_split_mb(mb_header* block, u32 size)
|
||||||
new_block->size = block->size - size - MB_HEADER_SIZE;
|
new_block->size = block->size - size - MB_HEADER_SIZE;
|
||||||
new_block->is_free = true;
|
new_block->is_free = true;
|
||||||
new_block->next = block->next;
|
new_block->next = block->next;
|
||||||
new_block->prev = block;
|
new_block->prev = axl_ptr_to_id(block);
|
||||||
|
|
||||||
if(new_block->next)
|
if(new_block->next)
|
||||||
{
|
{
|
||||||
new_block->next->prev = new_block;
|
axl_id_to_mb(new_block->next)->prev = axl_ptr_to_id(new_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
block->size = size;
|
block->size = size;
|
||||||
block->next = new_block;
|
block->next = axl_ptr_to_id(new_block);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -139,10 +167,10 @@ void* axl_malloc(u32 size)
|
||||||
axl_split_mb(free_block, size);
|
axl_split_mb(free_block, size);
|
||||||
free_block->is_free = false;
|
free_block->is_free = false;
|
||||||
|
|
||||||
nomad = free_block->next;
|
nomad_handle = free_block->next;
|
||||||
if(!nomad)
|
if(nomad_handle == AXL_INVALID_MB_HANDLE)
|
||||||
{
|
{
|
||||||
nomad = root;
|
nomad_handle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (void*)((u8*)free_block + MB_HEADER_SIZE);
|
return (void*)((u8*)free_block + MB_HEADER_SIZE);
|
||||||
|
|
@ -173,7 +201,7 @@ void* axl_realloc(void* ptr, u32 size)
|
||||||
return axl_malloc(size);
|
return axl_malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
mb_header* old = axl_get_mb_header(ptr);
|
mb_header* old = axl_ptr_to_mb(ptr);
|
||||||
if(axl_split_mb(old, size))
|
if(axl_split_mb(old, size))
|
||||||
{
|
{
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
@ -217,9 +245,9 @@ void axl_free(void* ptr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mb_header* block = axl_get_mb_header(ptr);
|
mb_header* block = axl_ptr_to_mb(ptr);
|
||||||
mb_header* next_block = block->next;
|
mb_header* next_block = axl_id_to_mb(block->next);
|
||||||
mb_header* prev_block = block->prev;
|
mb_header* prev_block = axl_id_to_mb(block->prev);
|
||||||
block->is_free = true;
|
block->is_free = true;
|
||||||
|
|
||||||
mb_header* free_block = block;
|
mb_header* free_block = block;
|
||||||
|
|
@ -230,7 +258,7 @@ void axl_free(void* ptr)
|
||||||
block->next = next_block->next;
|
block->next = next_block->next;
|
||||||
if(block->next)
|
if(block->next)
|
||||||
{
|
{
|
||||||
block->next->prev = block;
|
axl_id_to_mb(block->next)->prev = axl_ptr_to_id(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,10 +268,10 @@ void axl_free(void* ptr)
|
||||||
prev_block->next = block->next;
|
prev_block->next = block->next;
|
||||||
if(prev_block->next)
|
if(prev_block->next)
|
||||||
{
|
{
|
||||||
prev_block->next->prev = prev_block;
|
axl_id_to_mb(prev_block->next)->prev = axl_ptr_to_id(prev_block);
|
||||||
}
|
}
|
||||||
free_block = prev_block;
|
free_block = prev_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
nomad = free_block;
|
nomad_handle = axl_ptr_to_id(free_block);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue