Attempted to add a method of running deinitialisation code on arena destruction

This commit is contained in:
Warwick 2025-11-26 13:16:27 +00:00
parent 11b7d95fca
commit 4c6348a0ee
2 changed files with 26 additions and 4 deletions

View file

@ -65,6 +65,13 @@ void arena_deinit(Arena *arena) {
arena_deinit(current_child); arena_deinit(current_child);
} }
// Run deinit tasks before freeing data
while (arena->deinit_task_top != NULL) {
assert(arena->deinit_task_top->func_ptr != NULL);
arena->deinit_task_top->func_ptr(arena->deinit_task_top->func_param);
arena->deinit_task_top = arena->deinit_task_top->next;
}
// actually free the data // actually free the data
assert(arena->begin != NULL && arena->end != NULL); assert(arena->begin != NULL && arena->end != NULL);
Region *region = arena->begin; Region *region = arena->begin;
@ -117,7 +124,11 @@ void *arena_alloc(Arena *arena, size_t size) {
return result; return result;
} }
// void *arena_clear(Arena *arena) { void arena_run_on_deinit_push(Arena *arena, ArenaDeinitTask task) {
// arena->size = 0; ArenaDeinitTask *job = arena_alloc(arena, sizeof(ArenaDeinitTask));
// return arena->data; *job = task;
// }
ArenaDeinitTask *next_job = arena->deinit_task_top;
arena->deinit_task_top = job;
job->next = next_job;
}

View file

@ -10,6 +10,14 @@ struct Region_s {
unsigned char data[]; unsigned char data[];
}; };
typedef struct ArenaDeinitTask_s ArenaDeinitTask;
struct ArenaDeinitTask_s {
void *func_param;
void (*func_ptr)(void *);
ArenaDeinitTask *next;
};
ArenaDeinitTask ArenaDeinitTask_default = {NULL};
typedef struct Arena_s Arena; typedef struct Arena_s Arena;
struct Arena_s { struct Arena_s {
Arena *parent; Arena *parent;
@ -17,10 +25,13 @@ struct Arena_s {
Arena *sibling; Arena *sibling;
Region *begin; Region *begin;
Region *end; Region *end;
ArenaDeinitTask *deinit_task_top;
}; };
Arena *arena_init(Arena *parent, size_t capacity); Arena *arena_init(Arena *parent, size_t capacity);
void arena_deinit(Arena *arena); void arena_deinit(Arena *arena);
void arena_run_on_deinit_push(Arena *arena, ArenaDeinitTask task);
void *arena_alloc(Arena *arena, size_t size); void *arena_alloc(Arena *arena, size_t size);
// void *arena_clear(Arena *arena); // void *arena_clear(Arena *arena);