From 7f85664f131ef5f1b379352df7f94358d8aa3f4d Mon Sep 17 00:00:00 2001 From: Ivar Fatland Date: Wed, 26 Nov 2025 20:57:26 +0100 Subject: [PATCH] trying to find out what I dont understand --- cig.h | 15 +++++++-------- makefile | 8 +++++++- scratch.c | 43 ++++++++++++++++++++++++++++++++++++++++++ test_arena_allocator.c | 22 +++++++++++++++++++++ 4 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 scratch.c diff --git a/cig.h b/cig.h index e818eb6..b2b49fb 100644 --- a/cig.h +++ b/cig.h @@ -119,17 +119,12 @@ allocator_t borrow_allocator_interface(borrow_allocator_t *this); // memory chunk that is needed for a single frame. typedef struct arena_allocator { borrow_allocator_t borrow_allocator; - // Total size of bytes allocated. This allocator will only grow the - // allocated field as allocations are made, keeping track of the total - // memory allocated, and if the allocations have to be done in several - // chunks because your initial guess of how much memory was needed doesn't - // meet reality, all chunks will be freed, and then for the next - // initialization this total amount will be allocated as a single chunk. - // This freeing of memory happens on reset, the next alloc allocates the - // whole chunk. + // Set to 0 when instantiating. Will be updated as the borrow allocator is + // used. Is used on reset to allocate a continous chunk of memory. size_t total_allocated; uint8_t *bytes; } arena_allocator_t; + #define arena_allocator_create() \ (arena_allocator_t) { \ .borrow_allocator = borrow_allocator_create(), .total_allocated = 0, \ @@ -151,6 +146,10 @@ void arena_allocator_reset_func(arena_allocator_t *this, const char *file, int l void arena_allocator_destroy(arena_allocator_t *this); allocator_t arena_allocator_interface(arena_allocator_t *this); +// TODO: make the reset happen at the start, not the end. That allows the user +// to specify some starting size of the buffer. + +// You cannot use return within this block. #define with_arena(ARENA, ALLOCATOR_NAME) \ for (allocator_t ALLOCATOR_NAME = arena_allocator_interface(ARENA); \ ALLOCATOR_NAME.vtbl != NULL; \ diff --git a/makefile b/makefile index d34d956..5a7b0c0 100644 --- a/makefile +++ b/makefile @@ -5,7 +5,7 @@ LDFLAGS := -lcriterion TESTBIN := /tmp/all_tests -.PHONY: test +.PHONY: test scratch run_test: test $(TESTBIN) @@ -30,3 +30,9 @@ CRITERION_HEADERS := $(shell find /usr/include/criterion) ALL_FILES := $(PROJECT_C_FILES) $(CRITERION_HEADERS) tags: $(ALL_FILES) ctags -R $(ALL_FILES) + +scratch: /tmp/scratch + valgrind --leak-check=full --show-leak-kinds=all --error-exitcode=1 /tmp/scratch + +/tmp/scratch: scratch.c + gcc scratch.c -o /tmp/scratch diff --git a/scratch.c b/scratch.c new file mode 100644 index 0000000..ba32ab3 --- /dev/null +++ b/scratch.c @@ -0,0 +1,43 @@ +#define ALLOCATOR_IMPLEMENTATION +#include "cig.h" +#include +#include + +int main() { + // test 1/////////////////////////////////////////////////////////////////////// + arena_allocator_t aalloc = arena_allocator_create(); + + for ( int i = 0; i < 10; i++ ) with_arena(&aalloc, allocator) { + allocator_alloc(allocator, 10); + } + + assert(aalloc.total_allocated == 10); + assert(borrow_allocator_count_allocations(&aalloc.borrow_allocator) == 0); + assert(dyn_array_capacity(aalloc.bytes) == 10); + + arena_allocator_destroy(&aalloc); + assert(aalloc.total_allocated == 0); + arena_allocator_destroy(&aalloc); + + // test 2 ////////////////////////////////////////////////////////////////////// + aalloc = arena_allocator_create(); + + for ( int i = 0; i < 10; i++ ) with_arena(&aalloc, allocator) { + allocator_alloc(allocator, 1000); + } + + with_arena(&aalloc, allocator) { + size_t prev_addr = 0; + prev_addr = ~prev_addr; + for (int i = 0; i < 1001; i++) { + size_t addr = (size_t)allocator_alloc(allocator, 1); + assert(addr != prev_addr); + assert(addr % MAX_ALIGN == 0); + } + } + arena_allocator_reset(&aalloc); + fprintf(stderr, "%zu\n", aalloc.total_allocated); + //assert(aalloc.total_allocated == MAX_ALIGN * 1000 + 1); + // TODO: WHAT is happening here? + arena_allocator_destroy(&aalloc); +} diff --git a/test_arena_allocator.c b/test_arena_allocator.c index aa2bd80..3a6af03 100644 --- a/test_arena_allocator.c +++ b/test_arena_allocator.c @@ -1,5 +1,6 @@ #include #include "cig.h" +#include Test(arena_allocator, repeated_allocations) { arena_allocator_t aalloc = arena_allocator_create(); @@ -16,4 +17,25 @@ Test(arena_allocator, repeated_allocations) { cr_assert_eq(aalloc.total_allocated, 0); } +Test(arena_allocator, alignment) { + arena_allocator_t aalloc = arena_allocator_create(); + + for ( int i = 0; i < 10; i++ ) with_arena(&aalloc, allocator) { + allocator_alloc(allocator, 1000); + } + + with_arena(&aalloc, allocator) { + size_t prev_addr = 0; + prev_addr = ~prev_addr; + for (int i = 0; i < 1001; i++) { + size_t addr = (size_t)allocator_alloc(allocator, 1); + cr_assert_neq(addr, prev_addr); + cr_assert_eq(addr % MAX_ALIGN, 0); + } + } + arena_allocator_reset(&aalloc); + fprintf(stderr, "%zu\n", aalloc.total_allocated); + cr_assert_eq(aalloc.total_allocated, MAX_ALIGN * 1000 + 1); +} + // TODO somehow test reallocations