summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arena.h96
1 files changed, 81 insertions, 15 deletions
diff --git a/arena.h b/arena.h
index 9432ff4..474c251 100644
--- a/arena.h
+++ b/arena.h
@@ -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)