Răsfoiți Sursa

[arena.h] Adding missing libraries and chunks

Vinicius Teshima 1 an în urmă
părinte
comite
2871e132f5
1 a modificat fișierele cu 99 adăugiri și 36 ștergeri
  1. 99 36
      include/toolbox/arena.h

+ 99 - 36
include/toolbox/arena.h

@@ -2,49 +2,61 @@
 #define ARENA_H
 
 #include <stdint.h>
+#include <stdlib.h>
+
 
 typedef uint8_t err_t;
 
+struct arena_chunk {
+	uintptr_t start;
+	size_t size;
+};
+
 struct arena {
 	uint8_t *data;
 	size_t cur;
 	size_t cap;
+	struct {
+		struct arena_chunk *items;
+		size_t size;
+		size_t cap;
+	} chunks;
 };
 
-struct void_p_err_t {
-	void *ptr;
-	err_t err;
-};
-
-struct arena_void_p_err_t {
+struct arena_err_t {
 	struct arena arena;
-	void *ptr;
 	err_t err;
 };
 
-struct arena_err_t {
+struct arena_void_p_err_t {
 	struct arena arena;
 	err_t err;
+	void *ptr;
 };
 
 enum arena_err {
 	ARENA_ERR_OK = 0,
 	ARENA_ERR_MALLOC_FAIL,
-	ARENA_ERR_HIT_CAP
+	ARENA_ERR_HIT_CAP,
+	ARENA_ERR_INVALID_PTR
 };
 
 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);
+struct arena_void_p_err_t arena_alloc(struct arena arena, size_t size,
+				      _Bool zero_it);
+struct arena_err_t arena_free(struct arena arena, void *ptr);
+struct arena_err_t arena_forget(struct arena arena, _Bool zero_it);
 
-err_t arena_forget(struct arena *arena);
-struct arena_err_t arena_forget_pure(struct arena arena);
+err_t arena_dump_chunks(struct arena arena);
 
 #if defined(ARENA_IMP) || defined(IMP)
 
 #include <stdlib.h>
+#include <string.h>
+
+#include "da.h"
 
 struct arena_err_t
 arena_create(size_t cap)
@@ -61,6 +73,8 @@ arena_create(size_t cap)
 		.cur = 0
 	};
 
+	DA_CREATE(arena.chunks, sizeof(struct arena_chunk));
+
 	return (struct arena_err_t) { .arena = arena, .err = ARENA_ERR_OK };
 }
 
@@ -68,55 +82,104 @@ err_t
 arena_destroy(struct arena arena)
 {
 	free(arena.data);
+	DA_DESTROY(arena.chunks);
 	return ARENA_ERR_OK;
 }
 
-
-
-struct void_p_err_t
-arena_alloc(struct arena *arena, size_t size)
+struct arena_void_p_err_t
+arena_alloc(struct arena arena, size_t size, _Bool zero_it)
 {
-	if ( arena->cur + size >= arena->cap ) {
-		return (struct void_p_err_t) {
+	if ( arena.cur + size >= arena.cap ) {
+		return (struct arena_void_p_err_t) {
+			.arena = arena,
 			.ptr = NULL,
 			.err = ARENA_ERR_HIT_CAP
 		};
 	}
 
-	void * ptr = (void *) (arena->data + arena->cur);
-	arena->cur += size;
+	void *ptr = (void *) (arena.data + arena.cur);
+	arena.cur += size;
 
-	return (struct void_p_err_t) {
+	struct arena_chunk chunk = {
+		.start = (uintptr_t) ptr,
+		.size = size
+	};
+
+	DA_APPEND(arena.chunks, chunk);
+
+	if ( zero_it != 0 ) {
+		memset(ptr, 0, size);
+	}
+
+	return (struct arena_void_p_err_t) {
+		.arena = arena,
 		.ptr = ptr,
 		.err = ARENA_ERR_OK
 	};
 }
 
+struct arena_err_t
+arena_free(struct arena arena, void *ptr)
+{
+	uintptr_t p = (uintptr_t) ptr;
+	struct arena_chunk ac = {0};
+
+	_Bool found = 0;
+	size_t chunk_index = 0;
+	for ( ; chunk_index < arena.chunks.size; ++chunk_index ) {
+		ac = arena.chunks.items[chunk_index];
+		if ( ac.start == p ) {
+			found = 1;
+			break;
+		}
+	}
 
-struct arena_void_p_err_t
-arena_alloc_pure(struct arena arena, size_t size)
+	if ( found == 0 ) {
+		return (struct arena_err_t) {
+			.arena = arena,
+			.err = ARENA_ERR_INVALID_PTR
+		};
+	}
+
+	DA_DELETE(arena.chunks, chunk_index);
+
+	return (struct arena_err_t) {
+		.arena = arena,
+		.err = ARENA_ERR_OK
+	};
+}
+
+struct arena_err_t
+arena_forget(struct arena arena, _Bool zero_it)
 {
-	struct void_p_err_t vpet = arena_alloc(&arena, size);
-	return (struct arena_void_p_err_t) {
+	arena.cur = 0;
+	if ( zero_it != 0 ) {
+		memset(arena.data, 0, arena.cap);
+	}
+
+	DA_CLEAR(arena.chunks);
+
+	return (struct arena_err_t) {
 		.arena = arena,
-		.ptr = vpet.ptr,
-		.err = vpet.err
+		.err = ARENA_ERR_OK
 	};
 }
 
+
+#include <stdio.h>
+
 err_t
-arena_forget(struct arena *arena)
+arena_dump_chunks(struct arena arena)
 {
-	arena->cur = 0;
+	struct arena_chunk ac = {0};
+	printf("Allocated Chunks (%li)\n", arena.chunks.size);
+	for ( size_t i = 0; i < arena.chunks.size; ++i ) {
+		ac = arena.chunks.items[i];
+		printf("\tstart: %ld, size: %li\n", ac.start, ac.size);
+	}
 	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 */