about summary refs log tree commit diff stats
path: root/arena.c
diff options
context:
space:
mode:
Diffstat (limited to 'arena.c')
-rw-r--r--arena.c68
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;
 }