Compare commits
No commits in common. "61c29ee56430fb5d5d137e785c0aad396e829555" and "b59aedad89d4183135de4bd37ae8c8ae98b3e71b" have entirely different histories.
61c29ee564
...
b59aedad89
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,4 @@
|
|||||||
.cache
|
.cache
|
||||||
.vscode
|
.vscode
|
||||||
test*
|
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
libwapp.so
|
libwapp.so
|
||||||
|
32
compile
32
compile
@ -1,39 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
BUILD_TYPE="debug"
|
|
||||||
|
|
||||||
while [[ $# > 0 ]];do
|
|
||||||
case $1 in
|
|
||||||
--release)
|
|
||||||
BUILD_TYPE="release"
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
*|-*|--*)
|
|
||||||
echo "Unknown option $1"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
CC=clang
|
CC=clang
|
||||||
CFLAGS="-Wall -Werror -pedantic "
|
|
||||||
LIBFLAGS="-fPIC -shared"
|
|
||||||
INCLUDE="\
|
INCLUDE="\
|
||||||
$(find src -type d | xargs -I{} echo -n "-I{} ") \
|
$(find src -type d | xargs -I{} echo -n "-I{} ") \
|
||||||
"
|
"
|
||||||
SRC="\
|
SRC="\
|
||||||
$(find src -type f -name "*.c" | xargs -I{} echo -n "{} ") \
|
$(find src -type f -name *.c | xargs -I{} echo -n "{} ") \
|
||||||
"
|
"
|
||||||
if [[ $BUILD_TYPE == "release" ]]; then
|
CFLAGS="-O3 -shared -fPIC -Wall -Werror -pedantic"
|
||||||
CFLAGS+="-O3"
|
|
||||||
else
|
|
||||||
CFLAGS+="-g -fsanitize=address -fsanitize=undefined"
|
|
||||||
fi
|
|
||||||
|
|
||||||
OUT="libwapp.so"
|
OUT="libwapp.so"
|
||||||
|
|
||||||
(set -x ; $CC $CFLAGS $LIBFLAGS $INCLUDE $SRC -o $OUT)
|
(set -x ; $CC $CFLAGS $INCLUDE $SRC -o $OUT)
|
||||||
|
|
||||||
if [[ -f ./test.c ]]; then
|
|
||||||
(set -x ; $CC $CFLAGS $INCLUDE $SRC ./test.c -o test)
|
|
||||||
fi
|
|
||||||
|
@ -13,12 +13,27 @@
|
|||||||
|
|
||||||
#define ARENA_MINIMUM_CAPACITY 1024
|
#define ARENA_MINIMUM_CAPACITY 1024
|
||||||
|
|
||||||
struct arena {
|
typedef struct base_arena BaseArena;
|
||||||
|
struct base_arena {
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
u8 *offset;
|
u8 *offset;
|
||||||
u64 capacity;
|
u64 capacity;
|
||||||
|
BaseArena *prev;
|
||||||
|
BaseArena *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct growing_arena {
|
||||||
|
BaseArena *active_arena;
|
||||||
|
u64 count;
|
||||||
|
u64 initial_capacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal bool base_arena_init(BaseArena *arena, u64 capacity);
|
||||||
|
internal void *base_arena_alloc_aligned(BaseArena *arena, u64 size,
|
||||||
|
u64 alignment);
|
||||||
|
internal void base_arena_clear(BaseArena *arena);
|
||||||
|
internal void base_arena_destroy(BaseArena *arena);
|
||||||
|
|
||||||
// PUBLIC API
|
// PUBLIC API
|
||||||
|
|
||||||
bool wapp_mem_arena_init(Arena **arena, u64 base_capacity) {
|
bool wapp_mem_arena_init(Arena **arena, u64 base_capacity) {
|
||||||
@ -32,18 +47,19 @@ bool wapp_mem_arena_init(Arena **arena, u64 base_capacity) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 arena_capacity = base_capacity >= ARENA_MINIMUM_CAPACITY
|
arena_ptr->active_arena = (BaseArena *)calloc(1, sizeof(BaseArena));
|
||||||
? base_capacity
|
if (!(arena_ptr->active_arena)) {
|
||||||
: ARENA_MINIMUM_CAPACITY;
|
|
||||||
|
|
||||||
arena_ptr->buf = (u8 *)calloc(arena_capacity, sizeof(u8));
|
|
||||||
if (!(arena_ptr->buf)) {
|
|
||||||
wapp_mem_arena_destroy(arena);
|
wapp_mem_arena_destroy(arena);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
arena_ptr->capacity = arena_capacity;
|
if (!base_arena_init(arena_ptr->active_arena, base_capacity)) {
|
||||||
arena_ptr->offset = arena_ptr->buf;
|
wapp_mem_arena_destroy(arena);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
arena_ptr->count = 1;
|
||||||
|
arena_ptr->initial_capacity = base_capacity;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -53,6 +69,130 @@ void *wapp_mem_arena_alloc(Arena *arena, u64 size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment) {
|
void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment) {
|
||||||
|
if (!arena || !(arena->active_arena)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *output = base_arena_alloc_aligned(arena->active_arena, size, alignment);
|
||||||
|
if (!output) {
|
||||||
|
if (arena->active_arena->next) {
|
||||||
|
arena->active_arena = arena->active_arena->next;
|
||||||
|
} else {
|
||||||
|
arena->active_arena->next = (BaseArena *)calloc(1, sizeof(BaseArena));
|
||||||
|
if (!(arena->active_arena->next)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!base_arena_init(arena->active_arena->next,
|
||||||
|
arena->initial_capacity)) {
|
||||||
|
free(arena->active_arena->next);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
arena->active_arena->next->prev = arena->active_arena;
|
||||||
|
arena->active_arena = arena->active_arena->next;
|
||||||
|
|
||||||
|
++(arena->count);
|
||||||
|
}
|
||||||
|
|
||||||
|
output = base_arena_alloc_aligned(arena->active_arena, size, alignment);
|
||||||
|
if (!output) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(output, 0, size);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wapp_mem_arena_clear(Arena *arena) {
|
||||||
|
if (!arena) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseArena *last_active = NULL;
|
||||||
|
while (arena->active_arena) {
|
||||||
|
base_arena_clear(arena->active_arena);
|
||||||
|
|
||||||
|
last_active = arena->active_arena;
|
||||||
|
|
||||||
|
arena->active_arena = arena->active_arena->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
arena->active_arena = last_active;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wapp_mem_arena_destroy(Arena **arena) {
|
||||||
|
if (!arena) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Arena *arena_ptr = *arena;
|
||||||
|
if (!arena_ptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseArena *current;
|
||||||
|
BaseArena *next;
|
||||||
|
BaseArena *prev;
|
||||||
|
|
||||||
|
current = arena_ptr->active_arena->next;
|
||||||
|
while (current) {
|
||||||
|
next = current->next;
|
||||||
|
|
||||||
|
base_arena_destroy(current);
|
||||||
|
free(current);
|
||||||
|
|
||||||
|
current = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = arena_ptr->active_arena->prev;
|
||||||
|
while (current) {
|
||||||
|
prev = current->prev;
|
||||||
|
|
||||||
|
base_arena_destroy(current);
|
||||||
|
free(current);
|
||||||
|
|
||||||
|
current = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
base_arena_destroy(arena_ptr->active_arena);
|
||||||
|
|
||||||
|
free(arena_ptr->active_arena);
|
||||||
|
arena_ptr->active_arena = NULL;
|
||||||
|
|
||||||
|
arena_ptr->count = 0;
|
||||||
|
arena_ptr->initial_capacity = 0;
|
||||||
|
|
||||||
|
free(*arena);
|
||||||
|
*arena = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// INTERNAL FUNCTIONS
|
||||||
|
|
||||||
|
internal bool base_arena_init(BaseArena *arena, u64 capacity) {
|
||||||
|
if (!arena || arena->buf || capacity == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 arena_capacity =
|
||||||
|
capacity >= ARENA_MINIMUM_CAPACITY ? capacity : ARENA_MINIMUM_CAPACITY;
|
||||||
|
|
||||||
|
arena->buf = (u8 *)calloc(arena_capacity, sizeof(u8));
|
||||||
|
if (!(arena->buf)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
arena->capacity = arena_capacity;
|
||||||
|
arena->offset = arena->buf;
|
||||||
|
arena->prev = arena->next = NULL;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void *base_arena_alloc_aligned(BaseArena *arena, u64 size,
|
||||||
|
u64 alignment) {
|
||||||
if (!arena) {
|
if (!arena) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -66,12 +206,10 @@ void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment) {
|
|||||||
|
|
||||||
arena->offset = output + size;
|
arena->offset = output + size;
|
||||||
|
|
||||||
memset(output, 0, size);
|
|
||||||
|
|
||||||
return (void *)output;
|
return (void *)output;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wapp_mem_arena_clear(Arena *arena) {
|
internal void base_arena_clear(BaseArena *arena) {
|
||||||
if (!arena) {
|
if (!arena) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -80,19 +218,16 @@ void wapp_mem_arena_clear(Arena *arena) {
|
|||||||
arena->offset = arena->buf;
|
arena->offset = arena->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wapp_mem_arena_destroy(Arena **arena) {
|
internal void base_arena_destroy(BaseArena *arena) {
|
||||||
if (!arena) {
|
if (!arena) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Arena *arena_ptr = *arena;
|
if (arena->buf) {
|
||||||
if (arena_ptr->buf) {
|
free(arena->buf);
|
||||||
free(arena_ptr->buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arena_ptr->buf = arena_ptr->offset = NULL;
|
arena->buf = arena->offset = NULL;
|
||||||
arena_ptr->capacity = 0;
|
arena->capacity = 0;
|
||||||
|
arena->prev = arena->next = NULL;
|
||||||
free(*arena);
|
|
||||||
*arena = NULL;
|
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
typedef struct arena Arena;
|
typedef struct growing_arena Arena;
|
||||||
|
|
||||||
bool wapp_mem_arena_init(Arena **arena, u64 base_capacity);
|
bool wapp_mem_arena_init(Arena **arena, u64 base_capacity);
|
||||||
void *wapp_mem_arena_alloc(Arena *arena, u64 size);
|
void *wapp_mem_arena_alloc(Arena *arena, u64 size);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user