summaryrefslogtreecommitdiff
path: root/core/alloc.c
diff options
context:
space:
mode:
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);
}
}