diff options
author | Aryadev Chavali <aryadev@aryadevchavali.com> | 2024-11-01 08:10:43 +0000 |
---|---|---|
committer | Aryadev Chavali <aryadev@aryadevchavali.com> | 2024-11-01 08:13:11 +0000 |
commit | cf93eede6bbe790c8eda220fd2ac65a68941d687 (patch) | |
tree | a9a06237c18bc5401732d1507a5727b642ccbf7e | |
parent | 46f62c5d2c789fd6122daa02efcc4dff10f6a2b5 (diff) | |
download | prick-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.h | 12 |
1 files changed, 8 insertions, 4 deletions
@@ -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)); } |