From 4248f000f200c0a078496733b65cf61a525c356b Mon Sep 17 00:00:00 2001 From: Danny Holman Date: Mon, 14 Oct 2024 21:05:58 -0500 Subject: core: alloc: move mem_block alloc to helper func Move the logic that allocates and frees individual mem_block structs to their own helper functions. This should simplify the engine's memory API and fix a bug in rune_calloc that improperly allocated a mem_block. Signed-off-by: Danny Holman --- core/alloc.c | 83 ++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 27 deletions(-) diff --git a/core/alloc.c b/core/alloc.c index a9f335c..bec36bc 100644 --- a/core/alloc.c +++ b/core/alloc.c @@ -33,50 +33,80 @@ static struct mem_block* _find_block(void *ptr) { return NULL; } -void* rune_alloc(size_t sz) { - if (sz == 0) - return NULL; - +static struct mem_block* _alloc_block(size_t sz) { if (first_block.ptr == NULL) { - first_block.ptr = DEADBLOCK; + first_block.ptr == DEADBLOCK; first_block.sz = 0; } - struct mem_block *block = _find_free_block(sz); - if (block != NULL) { - block->free = 0; - return block->ptr; + struct mem_block *ret = _find_free_block(sz); + if (ret != NULL) { + ret->free = 0; + return ret->ptr; } - block = malloc(sizeof(struct mem_block)); - if (block == NULL) { + ret = malloc(sizeof(struct mem_block)); + if (ret == NULL) { log_output(LOG_ERROR, "Cannot allocate block of size %d", sz); return NULL; } - block->ptr = malloc(sz); - block->sz = sz; - block->free = 0; - list_add(&block->list, &first_block.list); + + ret->ptr = malloc(sz); + ret->sz = sz; + ret->free = 0; + list_add(&ret->list, &first_block.list); log_output(LOG_DEBUG, "Alloc'd block of size %d", sz); + return ret; +} + +static void _free_block(struct mem_block *block, int hard) { + if (hard == 1) { + list_del(&block->list); + log_output(LOG_DEBUG, "Freed block of size %d", block->sz); + free(block); + return; + } + block->free = 1; +} + +void* rune_alloc(size_t sz) { + if (sz == 0) + return NULL; + + struct mem_block *block = _find_free_block(sz); + if (block != NULL) { + block->free = 0; + return block->ptr; + } + + block = _alloc_block(sz); return block->ptr; } void* rune_calloc(size_t nmemb, size_t sz) { - void *ret = rune_alloc(sz); - for (size_t *i = (size_t*)ret; i < (size_t*)ret+sz; i++) - *i = nmemb; - return ret; + if (sz == 0) + return NULL; + + struct mem_block *block = _find_free_block(sz); + if (block != NULL) { + block->free = 0; + return block->ptr; + } + + block = _alloc_block(sz); + memset(block->ptr, 0, sz); + return block->ptr; } void* rune_realloc(void *ptr, size_t sz) { if (ptr == NULL || sz == 0) return rune_alloc(sz); - struct mem_block *block = _find_block(ptr); - void *new_ptr = rune_alloc(sz); - memcpy(new_ptr, ptr, block->sz); - block->free = 1; - return new_ptr; + struct mem_block *old = _find_block(ptr); + struct mem_block *new = _alloc_block(sz); + memcpy(new->ptr, old->ptr, old->sz); + old->free = 1; + return new->ptr; } void rune_free(void *ptr) { @@ -87,7 +117,6 @@ void rune_free(void *ptr) { if (block->free == 1) return; block->free = 1; - log_output(LOG_DEBUG, "Freed block of size %d", block->sz); } void rune_free_all(void) { @@ -100,8 +129,8 @@ void rune_free_all(void) { continue; } - if (block->ptr != NULL) - free(block->ptr); temp = temp->next; + if (block->ptr != NULL) + _free_block(block, 1); } } -- cgit v1.2.3