Jelajahi Sumber

[arena.h] Adding non reclaiming arena lib

Vinicius Teshima 1 tahun lalu
induk
melakukan
5851a11340
1 mengubah file dengan 123 tambahan dan 0 penghapusan
  1. 123 0
      include/toolbox/arena.h

+ 123 - 0
include/toolbox/arena.h

@@ -0,0 +1,123 @@
+#ifndef ARENA_H
+#define ARENA_H
+
+#include <stdint.h>
+
+typedef uint8_t err_t;
+
+struct arena {
+	uint8_t *data;
+	size_t cur;
+	size_t cap;
+};
+
+struct void_p_err_t {
+	void *ptr;
+	err_t err;
+};
+
+struct arena_void_p_err_t {
+	struct arena arena;
+	void *ptr;
+	err_t err;
+};
+
+struct arena_err_t {
+	struct arena arena;
+	err_t err;
+};
+
+enum arena_err {
+	ARENA_ERR_OK = 0,
+	ARENA_ERR_MALLOC_FAIL,
+	ARENA_ERR_HIT_CAP
+};
+
+struct arena_err_t arena_create(size_t cap);
+err_t arena_destroy(struct arena arena);
+
+struct void_p_err_t arena_alloc(struct arena *arena, size_t size);
+struct arena_void_p_err_t arena_alloc_pure(struct arena arena, size_t size);
+
+err_t arena_forget(struct arena *arena);
+struct arena_err_t arena_forget_pure(struct arena arena);
+
+#if defined(ARENA_IMP) || defined(IMP)
+
+#include <stdlib.h>
+
+struct arena_err_t
+arena_create(size_t cap)
+{
+	void *data = calloc(cap, sizeof(uint8_t));
+
+	if ( data == NULL ) {
+		return (struct arena_err_t) { .err = ARENA_ERR_MALLOC_FAIL };
+	}
+
+	struct arena arena = {
+		.data = data,
+		.cap = cap,
+		.cur = 0
+	};
+
+	return (struct arena_err_t) { .arena = arena, .err = ARENA_ERR_OK };
+}
+
+err_t
+arena_destroy(struct arena arena)
+{
+	free(arena.data);
+	return ARENA_ERR_OK;
+}
+
+
+
+struct void_p_err_t
+arena_alloc(struct arena *arena, size_t size)
+{
+	if ( arena->cur + size >= arena->cap ) {
+		return (struct void_p_err_t) {
+			.ptr = NULL,
+			.err = ARENA_ERR_HIT_CAP
+		};
+	}
+
+	void * ptr = (void *) (arena->data + arena->cur);
+	arena->cur += size;
+
+	return (struct void_p_err_t) {
+		.ptr = ptr,
+		.err = ARENA_ERR_OK
+	};
+}
+
+
+struct arena_void_p_err_t
+arena_alloc_pure(struct arena arena, size_t size)
+{
+	struct void_p_err_t vpet = arena_alloc(&arena, size);
+	return (struct arena_void_p_err_t) {
+		.arena = arena,
+		.ptr = vpet.ptr,
+		.err = vpet.err
+	};
+}
+
+err_t
+arena_forget(struct arena *arena)
+{
+	arena->cur = 0;
+	return ARENA_ERR_OK;
+}
+
+struct arena_err_t
+arena_forget_pure(struct arena arena)
+{
+	err_t err = arena_forget(&arena);
+	return (struct arena_err_t) { .arena = arena, .err = err };
+}
+
+#endif	/* ARENA_IMP || IMPLEMENTATIONS */
+
+#endif	/* ARENA_H */