|
@@ -2,49 +2,61 @@
|
|
|
#define ARENA_H
|
|
#define ARENA_H
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
#include <stdint.h>
|
|
|
|
|
+#include <stdlib.h>
|
|
|
|
|
+
|
|
|
|
|
|
|
|
typedef uint8_t err_t;
|
|
typedef uint8_t err_t;
|
|
|
|
|
|
|
|
|
|
+struct arena_chunk {
|
|
|
|
|
+ uintptr_t start;
|
|
|
|
|
+ size_t size;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
struct arena {
|
|
struct arena {
|
|
|
uint8_t *data;
|
|
uint8_t *data;
|
|
|
size_t cur;
|
|
size_t cur;
|
|
|
size_t cap;
|
|
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;
|
|
struct arena arena;
|
|
|
- void *ptr;
|
|
|
|
|
err_t err;
|
|
err_t err;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-struct arena_err_t {
|
|
|
|
|
|
|
+struct arena_void_p_err_t {
|
|
|
struct arena arena;
|
|
struct arena arena;
|
|
|
err_t err;
|
|
err_t err;
|
|
|
|
|
+ void *ptr;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
enum arena_err {
|
|
enum arena_err {
|
|
|
ARENA_ERR_OK = 0,
|
|
ARENA_ERR_OK = 0,
|
|
|
ARENA_ERR_MALLOC_FAIL,
|
|
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);
|
|
struct arena_err_t arena_create(size_t cap);
|
|
|
err_t arena_destroy(struct arena arena);
|
|
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)
|
|
#if defined(ARENA_IMP) || defined(IMP)
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include <stdlib.h>
|
|
|
|
|
+#include <string.h>
|
|
|
|
|
+
|
|
|
|
|
+#include "da.h"
|
|
|
|
|
|
|
|
struct arena_err_t
|
|
struct arena_err_t
|
|
|
arena_create(size_t cap)
|
|
arena_create(size_t cap)
|
|
@@ -61,6 +73,8 @@ arena_create(size_t cap)
|
|
|
.cur = 0
|
|
.cur = 0
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ DA_CREATE(arena.chunks, sizeof(struct arena_chunk));
|
|
|
|
|
+
|
|
|
return (struct arena_err_t) { .arena = arena, .err = ARENA_ERR_OK };
|
|
return (struct arena_err_t) { .arena = arena, .err = ARENA_ERR_OK };
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -68,55 +82,104 @@ err_t
|
|
|
arena_destroy(struct arena arena)
|
|
arena_destroy(struct arena arena)
|
|
|
{
|
|
{
|
|
|
free(arena.data);
|
|
free(arena.data);
|
|
|
|
|
+ DA_DESTROY(arena.chunks);
|
|
|
return ARENA_ERR_OK;
|
|
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,
|
|
.ptr = NULL,
|
|
|
.err = ARENA_ERR_HIT_CAP
|
|
.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,
|
|
.ptr = ptr,
|
|
|
.err = ARENA_ERR_OK
|
|
.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,
|
|
.arena = arena,
|
|
|
- .ptr = vpet.ptr,
|
|
|
|
|
- .err = vpet.err
|
|
|
|
|
|
|
+ .err = ARENA_ERR_OK
|
|
|
};
|
|
};
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
+#include <stdio.h>
|
|
|
|
|
+
|
|
|
err_t
|
|
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;
|
|
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_IMP || IMPLEMENTATIONS */
|
|
|
|
|
|