From 18a0832c5e78a53c8b69acaefc7dbfb7aa62fa11 Mon Sep 17 00:00:00 2001 From: Eric-Paul Ickhorn Date: Fri, 19 Jan 2024 22:05:57 +0100 Subject: [PATCH] Introduced generic allocator structures and modified the arena allocator functions to use one. --- platform/exports/librr/alloc/arena.h | 18 ++++-------- platform/exports/librr/alloc/generic.h | 38 ++++++++++++++++++++++++ platform/src-c/alloc/arena.c | 40 ++++++++++++++++++-------- 3 files changed, 71 insertions(+), 25 deletions(-) create mode 100644 platform/exports/librr/alloc/generic.h diff --git a/platform/exports/librr/alloc/arena.h b/platform/exports/librr/alloc/arena.h index 6831f3a..e9f7145 100644 --- a/platform/exports/librr/alloc/arena.h +++ b/platform/exports/librr/alloc/arena.h @@ -3,20 +3,12 @@ #define RR_ARENA_ALLOCATOR_H #include +#include -typedef struct rr_arena rr_arena_s; +rr_generic_arena_s rr_new_arena(usz_t capacity); +void rr_destruct_arena(rr_generic_arena_s *generic_arena); -struct rr_arena -{ - usz_t capacity; - usz_t offset; - char *allocation; -}; - -rr_arena_s rr_new_arena(usz_t capacity); -void rr_delete_arena(rr_arena_s *arena); - -void * rr_arena_alloc(rr_arena_s *arena, usz_t length); -char * rr_arena_clone_string(rr_arena_s *arena, const char *string); +void * rr_arena_alloc(rr_generic_arena_s *generic_arena, usz_t length); +char * rr_arena_clone_string(rr_generic_arena_s *generic_arena, const char *string); #endif // RR_ARENA_ALLOCATOR_H diff --git a/platform/exports/librr/alloc/generic.h b/platform/exports/librr/alloc/generic.h new file mode 100644 index 0000000..5829cac --- /dev/null +++ b/platform/exports/librr/alloc/generic.h @@ -0,0 +1,38 @@ + +#ifndef RR_GENERIC_ALLOCATOR_H +#define RR_GENERIC_ALLOCATOR_H + +#include + +typedef struct rr_generic_allocator rr_generic_allocator_s; +typedef struct rr_generic_pool rr_generic_pool_s; +typedef struct rr_generic_arena rr_generic_arena_s; + +typedef rr_generic_arena_s (*rr_create_arena_fn) (usz_t capacity); +typedef rr_generic_pool_s (*rr_create_pool_fn) (usz_t item_size, usz_t num_items); + +struct rr_generic_allocator +{ + void * (*fn_alloc) (rr_generic_allocator_s *allocator, usz_t num_bytes); + void (*fn_free) (rr_generic_allocator_s *allocator, void *block); + void (*fn_destruct) (rr_generic_allocator_s *allocator); + void *specifics; +}; + +struct rr_generic_pool +{ + void * (*fn_alloc) (rr_generic_pool_s *pool); + void (*fn_free) (rr_generic_pool_s *pool, void *block); + void (*fn_destruct) (rr_generic_pool_s *pool); + usz_t (*fn_get_unit_size) (rr_generic_pool_s *pool); + void *specifics; +}; + +struct rr_generic_arena +{ + void * (*fn_alloc) (rr_generic_arena_s *arena, usz_t num_bytes); + void (*fn_destruct) (rr_generic_arena_s *arena); + void *specifics; +}; + +#endif // RR_GENERIC_ALLOCATOR_H diff --git a/platform/src-c/alloc/arena.c b/platform/src-c/alloc/arena.c index 603a178..1cbbea1 100644 --- a/platform/src-c/alloc/arena.c +++ b/platform/src-c/alloc/arena.c @@ -4,26 +4,42 @@ #include -rr_arena_s rr_new_arena(usz_t capacity) +typedef struct rr_arena rr_arena_s; + +struct rr_arena { - rr_arena_s arena; - arena.capacity = capacity; - arena.offset = 0; - arena.allocation = malloc(capacity); + usz_t capacity; + usz_t offset; + char *allocation; +}; + +rr_generic_arena_s rr_new_arena(usz_t capacity) +{ + rr_arena_s *specifics = malloc(sizeof(rr_arena_s) + capacity); + specifics->capacity = capacity; + specifics->offset = 0; + // The arena allocation is right after the head structure. + specifics->allocation = (void *) (specifics + sizeof(rr_arena_s)); + + rr_generic_arena_s arena; + arena.fn_alloc = &rr_arena_alloc; + arena.fn_destruct = &rr_destruct_arena; + arena.specifics = specifics; + return arena; } -void rr_delete_arena(rr_arena_s *arena) +void rr_destruct_arena(rr_generic_arena_s *generic_arena) { - if(arena->allocation == NULL) return; - free(arena->allocation); - arena->allocation = NULL; + free(generic_arena->specifics); } -void * rr_arena_alloc(rr_arena_s *arena, usz_t length) +void * rr_arena_alloc(rr_generic_arena_s *generic_arena, usz_t length) { + rr_arena_s *arena = generic_arena->specifics; + if((arena->offset + length) > arena->capacity) return NULL; @@ -32,10 +48,10 @@ void * rr_arena_alloc(rr_arena_s *arena, usz_t length) return block; } -char * rr_arena_clone_string(rr_arena_s *arena, const char *string) +char * rr_arena_clone_string(rr_generic_arena_s *generic_arena, const char *string) { usz_t len_string = rr_measure_string(string); - char *cloned_string = rr_arena_alloc(arena, len_string+1); + char *cloned_string = rr_arena_alloc(generic_arena, len_string+1); if(cloned_string == NULL) return NULL; rr_memcopy(cloned_string, string, len_string);