Memory alignment, better realloc impl
This commit is contained in:
parent
5ee669909e
commit
349755a8eb
1 changed files with 56 additions and 17 deletions
73
axl_memory.c
73
axl_memory.c
|
|
@ -12,11 +12,18 @@ struct mb_header
|
|||
|
||||
typedef struct mb_header mb_header;
|
||||
|
||||
#define MB_HEADER_SIZE sizeof(mb_header)
|
||||
|
||||
static mb_header* root = NULL;
|
||||
static mb_header* nomad = NULL;
|
||||
|
||||
#define AXL_ALIGNMENT 8
|
||||
|
||||
static inline u32 axl_align(u32 size)
|
||||
{
|
||||
return (size + (AXL_ALIGNMENT - 1)) & ~(AXL_ALIGNMENT - 1);
|
||||
}
|
||||
|
||||
#define MB_HEADER_SIZE axl_align(sizeof(mb_header))
|
||||
|
||||
void* axl_memset(void* ptr, i8 c, u32 n)
|
||||
{
|
||||
if(ptr)
|
||||
|
|
@ -46,7 +53,7 @@ void axl_init(void)
|
|||
}
|
||||
}
|
||||
|
||||
static mb_header* axl_get_mb_header(void* ptr)
|
||||
static inline mb_header* axl_get_mb_header(void* ptr)
|
||||
{
|
||||
return (mb_header*)((u8*)ptr - MB_HEADER_SIZE);
|
||||
}
|
||||
|
|
@ -81,28 +88,42 @@ static mb_header* axl_find_mb(u32 req_size)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void axl_split_mb(mb_header* block, u32 size)
|
||||
static b8 axl_split_mb(mb_header* block, u32 size)
|
||||
{
|
||||
if(block->size > size + MB_HEADER_SIZE * 2)
|
||||
if(block->size > 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;
|
||||
new_block->prev = block;
|
||||
|
||||
if(new_block->next)
|
||||
if(block->size - size >= MB_HEADER_SIZE + AXL_ALIGNMENT)
|
||||
{
|
||||
new_block->next->prev = new_block;
|
||||
}
|
||||
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;
|
||||
new_block->prev = block;
|
||||
|
||||
block->size = size;
|
||||
block->next = new_block;
|
||||
if(new_block->next)
|
||||
{
|
||||
new_block->next->prev = new_block;
|
||||
}
|
||||
|
||||
block->size = size;
|
||||
block->next = new_block;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void* axl_malloc(u32 size)
|
||||
{
|
||||
if(size == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = axl_align(size);
|
||||
|
||||
if(size > AXL_HEAP_SIZE - MB_HEADER_SIZE)
|
||||
{
|
||||
return NULL;
|
||||
|
|
@ -139,6 +160,25 @@ void* axl_memcpy(void* dst, const void* src, u32 count)
|
|||
|
||||
void* axl_realloc(void* ptr, u32 size)
|
||||
{
|
||||
if(size == 0)
|
||||
{
|
||||
axl_free(ptr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = axl_align(size);
|
||||
|
||||
if(!ptr)
|
||||
{
|
||||
return axl_malloc(size);
|
||||
}
|
||||
|
||||
mb_header* old = axl_get_mb_header(ptr);
|
||||
if(axl_split_mb(old, size))
|
||||
{
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* new = axl_malloc(size);
|
||||
|
||||
if(!new)
|
||||
|
|
@ -146,7 +186,6 @@ void* axl_realloc(void* ptr, u32 size)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
mb_header* old = axl_get_mb_header(ptr);
|
||||
size = size < old->size ? size : old->size;
|
||||
axl_memcpy(new, ptr, size);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue