diff options
-rw-r--r-- | arena.h | 96 |
1 files changed, 81 insertions, 15 deletions
@@ -19,16 +19,95 @@ #include <stdint.h> -struct Region; +/** + @brief A single block of memory to be used by an arena. + + @details Blocks of memory arranged in a singly linked list. + Each individual node is a bump allocator. +*/ +typedef struct Region +{ + struct Region *next; + uint32_t size, capacity; + uint8_t bytes[]; +} region_t; + +/** + @brief Allocate a new region on the heap with requested size and a pointer to + the next region. + @details If capacity is less than REGION_DEFAULT_SIZE, capacity is set to + REGION_DEFAULT_SIZE. + */ +region_t *region_make(uint32_t capacity, region_t *next); + +/** + @brief Allocate memory of requested size on the region. + @details If the region cannot fit the requested size, then return NULL. + Otherwise return a pointer to the start of the allocated memory, incrementing + the region size appropriately. + */ +uint8_t *region_alloc_flat(region_t *region, uint32_t size); + +/** + @brief Allocate memory of requested size on the region. + @details Iterates through the linked list of regions to find an appropriately + sized region for the requested size, allocating a new region if one cannot be + found. This new region will have capacity at least size * + REGION_CAPACITY_MULT. + + Returns a pointer to the start of the allocated memory, incrementing the + appropriate region's size. + */ +uint8_t *region_alloc_rec(region_t *region, uint32_t size); + +/** + @brief Delete a region, freeing its memory. + @details Will free all regions following it in the linked list. + */ +void region_delete_rec(region_t *region); + typedef struct { - struct Region *beg, *end; + region_t *beg, *end; } arena_t; +/** + @brief Allocate memory of requested size in the arena, returning a pointer to + the start of it. + @details Uses region_alloc_rec internally to allocate the memory required. + arena->beg and arena->end are set appropriately for this task. + */ uint8_t *arena_alloc(arena_t *arena, uint32_t size); + +/** + @brief Reallocate buffer of old_size to a buffer of new_size in the + arena, returning a pointer to the start of the new buffer. + + @details If the pointer is not allocated in the arena, return NULL. If the + pointer and old_size cover a complete region reallocate the region itself to + fit the newly requested size, relinking it in the linked list. Otherwise, + allocate as per usual. + + The contents of the old memory are copied into the new buffer. If old_size > + new_size, only new_size bytes will be copied from the old buffer into the new + one. + */ uint8_t *arena_realloc(arena_t *arena, uint8_t *pointer, uint32_t old_size, uint32_t new_size); + +/** + @brief Reset the arena for reuse. + + @details Sets all regions to default values, setting size to 0. No memory is + deleted in this operation. + */ void arena_reset(arena_t *arena); + +/** + @brief Free the memory associated with the arena. + + @details Deletes all regions of memory associated in the arena. + */ void arena_free(arena_t *arena); #ifdef ARENA_IMPL @@ -45,19 +124,6 @@ void arena_free(arena_t *arena); #endif #define MAX(A, B) ((A) > (B) ? (A) : (B)) - -/** - @brief A single block of memory to be used by an arena. - - @details Blocks of memory arranged in a singly linked list. - Each individual node is a bump allocator. -*/ -typedef struct Region -{ - struct Region *next; - uint32_t size, capacity; - uint8_t bytes[]; -} region_t; #define MIN(A, B) ((A) < (B) ? (A) : (B)) region_t *region_make(uint32_t capacity, region_t *next) |