From 7ebd70c59cc3184c08434a4327c86b945d2a0ac9 Mon Sep 17 00:00:00 2001 From: Eric-Paul Ickhorn Date: Thu, 23 May 2024 00:12:26 +0200 Subject: [PATCH] Added arena library --- inc-c/ufn/ufn_arena.h | 96 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 inc-c/ufn/ufn_arena.h diff --git a/inc-c/ufn/ufn_arena.h b/inc-c/ufn/ufn_arena.h new file mode 100644 index 0000000..de3937e --- /dev/null +++ b/inc-c/ufn/ufn_arena.h @@ -0,0 +1,96 @@ +// UFN Arena library. MIT-Licensed (c) Eric-Paul Ickhorn (epickh) + +#ifndef UFN_ARENA_H +#define UFN_ARENA_H + +#include + +#define UFN_UNLIMITED_ARENA 0xffffffff + +typedef struct ufn_arena ufn_arena_s; + +struct ufn_arena +{ + uint32_t capacity; + uint32_t usage; + char *allocation; + + uint32_t maximum; + ufn_arena_s *continuation; +}; + +ufn_arena_s * ufn_new_dynamic_arena(uint32_t capacity, uint32_t max_tree_size); +ufn_arena_s * ufn_new_static_arena(uint32_t capacity); +void ufn_free_arena(ufn_arena_s *arena); + +void * ufn_arena_alloc(ufn_arena_s *arena, uint32_t size); + + + +#ifdef UFN_IMPLEMENTATION + +#include + +ufn_arena_s * ufn_new_dynamic_arena(uint32_t capacity, uint32_t max_tree_size) +{ + ufn_arena_s *arena = malloc(sizeof(ufn_arena_s)); + arena->capacity = capacity; + arena->usage = 0; + arena->allocation = malloc(capacity); + arena->maximum = max_tree_size; + arena->continuation = NULL; + return arena; +} +ufn_arena_s * ufn_new_static_arena(uint32_t capacity) +{ + return ufn_new_dynamic_arena(capacity, 0); +} + +void ufn_free_arena(ufn_arena_s *arena) +{ + if(arena->continuation != NULL) + { + ufn_free_arena(arena->continuation); + } + free(arena->allocation); + free(arena); +} + +void * ufn_arena_alloc(ufn_arena_s *arena, uint32_t size) +{ + if((arena->usage = size) >= arena->capacity) + { + if(arena->continuation == NULL) + { + uint32_t continuation_size = arena->capacity * 2; + // Clamp the continuation's size to the maximum allowed one. + if(continuation_size > (arena->maximum)) + { + continuation_size = arena->maximum; + } + uint32_t continued_maximum = continuation_size - arena->maximum; + // If no continuation of this arena tree can fulfill + // a request of this size, + // -> Deny the request and return NULL. + if(size > arena->maximum) + { + return NULL; + } + // If no more arena can be allocated (The tree has its maximum size) + // -> return NULL. + if(continuation_size == 0) + { + return NULL; + } + arena->continuation = ufn_new_dynamic_arena(continuation_size, continued_maximum); + } + ufn_arena_alloc(arena->continuation, size); + } + void *block = arena->allocation + arena->usage; + arena->usage += size; + return block; +} + + +#endif // UFN_IMPLEMENTATION +#endif // UFN_ARENA_H