diff options
Diffstat (limited to 'arena.c')
-rw-r--r-- | arena.c | 68 |
1 files changed, 36 insertions, 32 deletions
diff --git a/arena.c b/arena.c index 9e15c2a..bf78edc 100644 --- a/arena.c +++ b/arena.c @@ -1,47 +1,49 @@ +#include "arena.h" + #include <assert.h> #include <stdlib.h> #include <string.h> -#include "arena.h" - -union align { - long long int l; - long double d; - void *p; -}; +/* + * Alignment for largest scalar type. Before max_align_t was added in C11, code + * like this usually declared a union of several long-ish types, resulting in a + * suitable sizeof result. Hopefully anyway. This is cleaner. + */ +#define ALIGN (sizeof(max_align_t)) -/* alignment for a long-ish builtin type? */ -#define ALIGN (sizeof(union align)) -/* ensure it's a power of two */ -static_assert(ALIGN && !(ALIGN & (ALIGN - 1)), "ALIGN not power of two"); +/* + * We need this property below to round up to multiples of `ALIGN`. (Of course + * it's almost certainly true anyway.) + */ +static_assert(ALIGN && !(ALIGN & (ALIGN - 1)), "ALIGN not a power of two"); -static unsigned char *data; -static size_t total; -static size_t used; +static unsigned char *arena; /* memory allocated for the arena */ +static size_t capacity; /* capacity of the arena in bytes */ +static size_t used; /* bytes used so far (from beginning) */ /* - * round up to nearest multiple of ALIGN + * Round up `minimum` to nearest multiple of ALIGN. */ -static size_t +static inline size_t round_up(size_t minimum) { return (minimum + ALIGN - 1) & ~(ALIGN - 1); } int -ar_setup(size_t total_size) +ar_setup(size_t arena_size) { - assert(data == NULL); + assert(!arena); - size_t adjusted = round_up(total_size); + size_t adjusted = round_up(arena_size); void *p = calloc(1, adjusted); if (p == NULL) { return -1; } - data = p; - total = adjusted; + arena = p; + capacity = adjusted; return 0; } @@ -49,14 +51,14 @@ ar_setup(size_t total_size) void * ar_alloc(size_t object_size) { - assert(data != NULL); + assert(arena); - size_t adjusted = round_up(object_size); - if (used + adjusted > total) { - return NULL; + size_t adjusted = round_up(object_size); /* keep `used` aligned */ + if (used + adjusted > capacity) { + return NULL; /* out of space */ } - void *p = data + used; + void *p = arena + used; used += adjusted; return p; @@ -65,18 +67,20 @@ ar_alloc(size_t object_size) void ar_free(void) { - assert(data != NULL); + assert(arena); - memset(data, 0, total); + memset(arena, 0, capacity); used = 0; } void ar_cleanup(void) { - assert(data != NULL); - free(data); - data = NULL; - total = 0; + assert(arena); + + free(arena); + arena = NULL; + + capacity = 0; used = 0; } |