summaryrefslogtreecommitdiff
path: root/core/alloc.c
diff options
context:
space:
mode:
authorDanny Holman <dholman@gymli.org>2024-10-14 21:05:58 -0500
committerDanny Holman <dholman@gymli.org>2024-10-14 21:05:58 -0500
commit4248f000f200c0a078496733b65cf61a525c356b (patch)
tree7e2754fea0d3dd1347d213c28e6846af344b7a0c /core/alloc.c
parent7ec4bf7c73869fbf641dd642d8e413afc2e0a829 (diff)
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 <dholman@gymli.org>
Diffstat (limited to 'core/alloc.c')
-rw-r--r--core/alloc.c83
1 files 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);
}
}