summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAryadev Chavali <aryadev@aryadevchavali.com>2024-11-01 08:10:43 +0000
committerAryadev Chavali <aryadev@aryadevchavali.com>2024-11-01 08:13:11 +0000
commitcf93eede6bbe790c8eda220fd2ac65a68941d687 (patch)
treea9a06237c18bc5401732d1507a5727b642ccbf7e
parent46f62c5d2c789fd6122daa02efcc4dff10f6a2b5 (diff)
downloadprick-cf93eede6bbe790c8eda220fd2ac65a68941d687.tar.gz
prick-cf93eede6bbe790c8eda220fd2ac65a68941d687.tar.bz2
prick-cf93eede6bbe790c8eda220fd2ac65a68941d687.zip
region_delete->region_delete_rec and slightly rework arena_realloc
1) Better naming. 2) Use MIN macro for choosing the size to copy over from the old buffer to the new one. Also fix issue where we free the old region of memory before copying it over to the new buffer.
-rw-r--r--arena.h12
1 files changed, 8 insertions, 4 deletions
diff --git a/arena.h b/arena.h
index cedab26..319384c 100644
--- a/arena.h
+++ b/arena.h
@@ -58,6 +58,7 @@ typedef struct Region
uint32_t size, capacity;
uint8_t bytes[];
} region_t;
+#define MIN(A, B) ((A) < (B) ? (A) : (B))
region_t *region_make(uint32_t capacity, region_t *next)
{
@@ -91,7 +92,7 @@ uint8_t *region_alloc_rec(region_t *region, uint32_t capacity)
return start;
}
-void region_delete(region_t *region)
+void region_delete_rec(region_t *region)
{
while (region)
{
@@ -130,17 +131,18 @@ uint8_t *arena_realloc(arena_t *arena, uint8_t *pointer, uint32_t old_size,
// pointer isn't allocated in the arena
return NULL;
+ int cleanup = 0;
uint8_t *new_ptr = NULL;
if (old_size == reg->size && reg->capacity == reg->size)
{
// Completely filled region, may as well reallocate
+ cleanup = 1;
region_t *new_reg = region_make(new_size * REGION_CAPACITY_MULT, reg->next);
// Chain this new region in place
if (prev)
prev->next = new_reg;
if (reg == arena->end)
arena->end = new_reg;
- free(reg);
new_ptr = new_reg->bytes;
new_reg->size += new_size;
}
@@ -149,13 +151,15 @@ uint8_t *arena_realloc(arena_t *arena, uint8_t *pointer, uint32_t old_size,
// Allocate a new portion of memory on the arena
new_ptr = arena_alloc(arena, new_size);
}
- memcpy(new_ptr, pointer, old_size);
+ memcpy(new_ptr, pointer, MIN(old_size, new_size));
+ if (cleanup)
+ free(reg);
return new_ptr;
}
void arena_free(arena_t *arena)
{
- region_delete(arena->beg);
+ region_delete_rec(arena->beg);
memset(arena, 0, sizeof(*arena));
}