diff --git a/src/arena_allocator.c b/src/arena_allocator.c index 1c94beb..2656040 100644 --- a/src/arena_allocator.c +++ b/src/arena_allocator.c @@ -11,19 +11,49 @@ Region *new_region(size_t capacity) { } Region *region = malloc(capacity + sizeof(Region)); assert(region != NULL); - *region = (Region){.next = NULL, - .capacity = capacity, - .cursor = 0}; + *region = (Region){.next = NULL, .capacity = capacity, .cursor = 0}; return region; } -Arena arena_init(size_t capacity) { +Arena arena_init(Arena *parent, size_t capacity) { Region *region = new_region(capacity); - Arena arena = {.begin = region, .end = region}; + + if (parent != NULL) { + // Allocate new arena in parent to reduce likelyhood of loss + Arena *current_arena = arena_alloc(parent, sizeof(Arena)); + *current_arena = (Arena){ + .begin = region, .end = region, .child = NULL, .sibling = NULL}; + + // if parent has no children this arena is now it's child + if (parent->child == NULL) { + parent->child = current_arena; + return *current_arena; + } + + // Push the arena onto the first childs sibling list + current_arena->sibling = parent->child; + parent->child = current_arena; + return *current_arena; + } + + // This is the root of the arena tree + Arena arena = { + .begin = region, .end = region, .child = NULL, .sibling = NULL}; return arena; } void arena_deinit(Arena *arena) { + if (arena == NULL) { + return; + } + // Recursively deinit children + while (arena->child != NULL) { + Arena *current_child = arena->child; + arena->child = current_child->sibling; + arena_deinit(current_child); + } + + // actually free the data assert(arena->begin != NULL && arena->end != NULL); Region *region = arena->begin; while (region != NULL) { @@ -31,6 +61,7 @@ void arena_deinit(Arena *arena) { free(region); region = next_region; } + *arena = (Arena){.begin = NULL, .end = NULL}; } diff --git a/src/arena_allocator.h b/src/arena_allocator.h index 9209bb7..423eedf 100644 --- a/src/arena_allocator.h +++ b/src/arena_allocator.h @@ -1,7 +1,6 @@ #pragma once #include -#include typedef struct Region_s Region; struct Region_s { @@ -11,13 +10,16 @@ struct Region_s { unsigned char data[]; }; -typedef struct { +typedef struct Arena_s Arena; +struct Arena_s { + Arena *child; + Arena *sibling; Region *begin; Region *end; -} Arena; +}; -Arena arena_init(size_t capacity); +Arena arena_init(Arena *parent, size_t capacity); void arena_deinit(Arena *arena); void *arena_alloc(Arena *arena, size_t size); -//void *arena_clear(Arena *arena); +// void *arena_clear(Arena *arena); diff --git a/src/main.c b/src/main.c index 4c2facd..2f94416 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "SDL3/SDL_events.h" @@ -10,16 +11,28 @@ #include "arena_allocator.h" -/*int main(int argc, char *argv[]) { - Arena global_arena = arena_init(0); +int main(int argc, char *argv[]) { + // arena allocation test + printf("Allocation test"); + Arena global_arena = arena_init(NULL, 0); for (int i = 0; i <= 1048576+100; i++) { int *number = arena_alloc(&global_arena, sizeof(int)); *number = 42; } - arena_deinit(&global_arena); -}*/ -int main(int argc, char *argv[]) { + printf("children test"); + + // arena children test + Arena child_arena = arena_init(&global_arena, 0); + //Arena sibling_arena = arena_init(&global_arena, 0); + //Arena grandchild_arena = arena_init(&child_arena, 0); + + arena_deinit(&global_arena); + + +} + +/*int main(int argc, char *argv[]) { wn_window window = {0}; if (!wn_window_init(&window)) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize wn_window"); @@ -132,4 +145,4 @@ int main(int argc, char *argv[]) { wn_window_deinit(&window); return EXIT_SUCCESS; -} +}*/