diff --git a/Makefile b/Makefile index 33166da..0872457 100644 --- a/Makefile +++ b/Makefile @@ -10,3 +10,4 @@ include make/libprocess.mk include make/libstring.mk include make/libkb.mk include make/libaux.mk +include make/libarena.mk diff --git a/aux/compiledb.sh b/aux/compiledb.sh index f33b07e..903a820 100755 --- a/aux/compiledb.sh +++ b/aux/compiledb.sh @@ -10,3 +10,4 @@ make -B all_compiledb_libterminal make -B all_compiledb_libstring make -B all_compiledb_libkb make -B all_compiledb_libaux +make -B all_compiledb_libarena diff --git a/aux/devel.sh b/aux/devel.sh index 57c271e..254af40 100755 --- a/aux/devel.sh +++ b/aux/devel.sh @@ -15,6 +15,7 @@ make -B all_libterminal make -B all_libstring make -B all_libkb make -B all_libaux +make -B all_libarena make -B all_apps make -B all_dist ./aux/limine_iso_amd64.sh diff --git a/aux/docs.sh b/aux/docs.sh index f658de1..cc94b26 100755 --- a/aux/docs.sh +++ b/aux/docs.sh @@ -11,5 +11,6 @@ make -B docs_libstring make -B docs_libterminal make -B docs_libkb make -B docs_libaux +make -B docs_libarena mkdocs build diff --git a/aux/format.sh b/aux/format.sh index 62f738d..6c4bf1e 100755 --- a/aux/format.sh +++ b/aux/format.sh @@ -10,4 +10,5 @@ make -B format_liballoc make -B format_libstring make -B format_libkb make -B format_libaux +make -B format_libarena make -B format_apps diff --git a/libarena/.gitignore b/libarena/.gitignore new file mode 100644 index 0000000..de276e3 --- /dev/null +++ b/libarena/.gitignore @@ -0,0 +1,4 @@ +*.o +*.json +docs/ +.cache/ diff --git a/libarena/Makefile b/libarena/Makefile new file mode 100644 index 0000000..13493b8 --- /dev/null +++ b/libarena/Makefile @@ -0,0 +1,7 @@ +include ../make/ufuncs.mk + +$(eval $(call add_include,liballoc)) + +libname := libarena + +include ../make/lib.mk diff --git a/libarena/arena.c b/libarena/arena.c new file mode 100644 index 0000000..a8c0246 --- /dev/null +++ b/libarena/arena.c @@ -0,0 +1,78 @@ +#include +#include +#include + +static struct arena_chunk* arena_create_chunk (size_t capacity) { + size_t size = sizeof (struct arena_chunk) + sizeof (uintptr_t) * capacity; + struct arena_chunk* chunk = malloc (size); + + if (chunk == NULL) + return NULL; + + chunk->next = NULL; + chunk->size = 0; + chunk->capacity = capacity; + return chunk; +} + +static void arena_destroy_chunk (struct arena_chunk* chunk) { free (chunk); } + +void arena_reset (struct arena* arena) { + for (struct arena_chunk* chunk = arena->begin; chunk != NULL; chunk = chunk->next) { + chunk->size = 0; + } + + arena->end = arena->begin; +} + +void arena_destroy (struct arena* arena) { + struct arena_chunk* chunk = arena->begin; + + while (chunk) { + struct arena_chunk* chunk1 = chunk; + chunk = chunk->next; + arena_destroy_chunk (chunk1); + } + + arena->begin = NULL; + arena->end = NULL; +} + +void* arena_malloc (struct arena* arena, size_t size) { + size_t size1 = (size + sizeof (uintptr_t) - 1) / sizeof (uintptr_t); + + if (arena->end == NULL) { + size_t capacity = ARENA_CHUNK_CAPACITY; + + if (capacity < size1) { + capacity = size1; + } + + arena->end = arena_create_chunk (capacity); + + if (arena->end == NULL) { + return NULL; + } + + arena->begin = arena->end; + } + + while (arena->end->size + size1 > arena->end->capacity && arena->end->next != NULL) { + arena->end = arena->end->next; + } + + if (arena->end->size + size1 > arena->end->capacity) { + size_t capacity = ARENA_CHUNK_CAPACITY; + + if (capacity < size1) { + capacity = size1; + } + + arena->end = arena_create_chunk (capacity); + arena->end = arena->end->next; + } + + void* result = &arena->end->memory[arena->end->size]; + arena->end->size += size1; + return result; +} diff --git a/libarena/arena.h b/libarena/arena.h new file mode 100644 index 0000000..31ef78a --- /dev/null +++ b/libarena/arena.h @@ -0,0 +1,25 @@ +#ifndef _LIBARENA_ARENA_H +#define _LIBARENA_ARENA_H + +#include + +#define ARENA_CHUNK_CAPACITY (8 * 1024) + +struct arena_chunk { + struct arena_chunk* next; + size_t capacity; + size_t size; + uintptr_t memory[]; +}; + +struct arena { + struct arena_chunk *begin, *end; +}; + +void arena_reset (struct arena* arena); + +void arena_destroy (struct arena* arena); + +void* arena_malloc (struct arena* arena, size_t size); + +#endif // _LIBARENA_ARENA_H diff --git a/libarena/src.mk b/libarena/src.mk new file mode 100644 index 0000000..80a4429 --- /dev/null +++ b/libarena/src.mk @@ -0,0 +1,3 @@ +c += arena.c + +o += arena.o diff --git a/make/libarena.mk b/make/libarena.mk new file mode 100644 index 0000000..fbb4fec --- /dev/null +++ b/make/libarena.mk @@ -0,0 +1,16 @@ +all_libarena: + make -C libarena platform=$(platform) all + +all_compiledb_libarena: + bear --output libarena/compile_commands.json -- make -C libarena platform=$(platform) all + +clean_libarena: + make -C libarena platform=$(platform) clean + +format_libarena: + make -C libarena platform=$(platform) format + +docs_libarena: + make -C libarena platform=$(platform) docs + +.PHONY: all_libarena clean_libarena format_libarena docs_libarena all_compiledb_libarena