// 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