From 9a93876137b86b30b6eadea29bc950031765dc8a Mon Sep 17 00:00:00 2001 From: Ivar Fatland Date: Fri, 5 Dec 2025 21:33:35 +0100 Subject: [PATCH] first draft of arena resize --- arena_allocator.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/arena_allocator.c b/arena_allocator.c index b0d2988..cd8894f 100644 --- a/arena_allocator.c +++ b/arena_allocator.c @@ -1,5 +1,6 @@ #include "cig.h" #include +#include static void arena_reset(arena_allocator_t *this) { if (0 < this->bytes_outside_data) { @@ -31,8 +32,41 @@ static void *arena_alloc(arena_allocator_t *this, size_t bytes) { } static void *arena_resize(arena_allocator_t *this, void *old_ptr, size_t bytes) { - bool is_old_ptr_in_data = this->data <= old_ptr && old_ptr < &this->data[this->size] - // TODO: implement this + uint8_t *old_ptr_b = (uint8_t *) old_ptr; + + bool is_old_ptr_in_data = + this->data <= old_ptr_b && + old_ptr_b < &this->data[this->capacity]; + + if (is_old_ptr_in_data) { + assert( + old_ptr_b < &this->data[this->size] && + "You cannot resize a pointer you got from before this allocator was reset.\n" + "You should not store pointer gotten from this allocator across resets.\n" + ); + } + + if (!is_old_ptr_in_data) { + // just a guess for how many extra bytes were allocated. + this->bytes_outside_data += bytes / 2; + return allocator_resize(this->allocator, old_ptr, bytes); + } + + uint8_t *new_ptr_b = arena_alloc(this, bytes); + if (new_ptr_b == NULL) { + return NULL; + } + + // sizeof not necessary but ill do it anyways. + size_t old_index = ((size_t)old_ptr - (size_t)this->data) / sizeof(*this->data); + size_t bytes_til_buffer_end = old_index + this->size; + size_t max_bytes_to_copy = bytes < bytes_til_buffer_end + ? bytes + : bytes_til_buffer_end; + for (size_t i = old_index; i < old_index + max_bytes_to_copy; i++) { + new_ptr_b[i] = this->data[i]; + } + return new_ptr_b; } // typedef struct arena_allocator {