From 5e92c4eaeae4432d7613ad64c8d68354ef129323 Mon Sep 17 00:00:00 2001 From: olemorud Date: Sun, 14 May 2023 23:57:05 +0200 Subject: [PATCH] Add makefile and restructure --- Makefile | 27 ++++++++++++++++++ arena_alloc.c | 63 ------------------------------------------ src/alloc_backend.c | 30 ++++++++++++++++++++ src/alloc_backend.h | 9 ++++++ src/arena.c | 60 ++++++++++++++++++++++++++++++++++++++++ arena.h => src/arena.h | 13 +++++++-- src/test_arena.c | 44 +++++++++++++++++++++++++++++ test_arena_alloc.c | 31 --------------------- 8 files changed, 180 insertions(+), 97 deletions(-) create mode 100644 Makefile delete mode 100644 arena_alloc.c create mode 100644 src/alloc_backend.c create mode 100644 src/alloc_backend.h create mode 100644 src/arena.c rename arena.h => src/arena.h (64%) create mode 100644 src/test_arena.c delete mode 100644 test_arena_alloc.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b822d6d --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ + +CC := gcc +CFLAGS := -ggdb -O0 -std=c99 -Wall -Wextra -Wpedantic + +OBJS := obj/arena.o obj/alloc_backend.o + +all : test/test_arena + +test/test_arena : src/test_arena.c $(OBJS) | test + $(CC) -o $@ $(CFLAGS) $^ + +obj/%.o : src/%.c | obj + $(CC) -o $@ -c $(CFLAGS) $< + +obj: + mkdir -p $@ + +bin: + mkdir -p $@ + +test: + mkdir -p $@ + +clean: + rm -rf obj bin test + +.PHONY: clean obj test bin all diff --git a/arena_alloc.c b/arena_alloc.c deleted file mode 100644 index cbf9f49..0000000 --- a/arena_alloc.c +++ /dev/null @@ -1,63 +0,0 @@ - - -#include "arena.h" -#include -#include -#include -#include // ptrdiff_t -#include - -#define ARENA_PAGES ((size_t)(128)) - -#define ALIGN 1 - -struct arena* arena_new() -{ - size_t page_size = sysconf(_SC_PAGE_SIZE); - size_t size = page_size * ARENA_PAGES; - - void *p = mmap( - NULL, - size, - PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE, - -1, /* man mmap(2): "[...], some implementations require fd to be - -1 if MAP_ANONYMOUS is specified [...]" */ - 0 - ); - - if (p == MAP_FAILED) { - return NULL; - } - - struct arena a = { - .start = p + sizeof(struct arena), - .next = p + sizeof(struct arena), - .cap = size - }; - - memcpy(p, &a, sizeof a); - - return p; -} - - -void arena_reset(struct arena *a) -{ - a->next = a->start; -} - - -void* arena_alloc(struct arena *a, size_t len) -{ - void *p = a->next; - a->next += len; - - if (a->next - a->start >= a->cap) { - errno = ENOMEM; - return NULL; - } - - return p; -} - diff --git a/src/alloc_backend.c b/src/alloc_backend.c new file mode 100644 index 0000000..1657cbb --- /dev/null +++ b/src/alloc_backend.c @@ -0,0 +1,30 @@ + +#include "alloc_backend.h" + +#define _GNU_SOURCE +#include + +/* + * Separate function to make switching + * allocation backend easier + * + * must take size_t size as an argument + * must return NULL on failure + */ +void* call_alloc_backend(size_t size) +{ + void *p = mmap( + NULL, + size, + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, + -1, /* man mmap(2): "[...], some implementations require fd to be + -1 if MAP_ANONYMOUS is specified [...]" */ + 0 + ); + + if (p == MAP_FAILED) + return NULL; + + return p; +} diff --git a/src/alloc_backend.h b/src/alloc_backend.h new file mode 100644 index 0000000..b234ea9 --- /dev/null +++ b/src/alloc_backend.h @@ -0,0 +1,9 @@ + +#ifndef ALLOC_BACKEND_H +#define ALLOC_BACKEND_H + +#include + +void* call_alloc_backend(size_t size); + +#endif diff --git a/src/arena.c b/src/arena.c new file mode 100644 index 0000000..397ea15 --- /dev/null +++ b/src/arena.c @@ -0,0 +1,60 @@ + + +#include "arena.h" +#include "alloc_backend.h" + +#include +#include +#include + +#define ARENA_SIZE ((size_t)(128*sysconf(_SC_PAGE_SIZE))) + +/* + * Allocates and returns new arena + */ +struct arena* arena_new() +{ + size_t size = ARENA_SIZE; + + unsigned char *p = call_alloc_backend(size); + + if (p == NULL) + return NULL; + + struct arena a = { + .begin = p + sizeof(struct arena), + .next = p + sizeof(struct arena), + .cap = size + }; + + memcpy(p, &a, sizeof a); + + return (struct arena*)p; +} + + +/* + * Frees all memory in arena + */ +void arena_reset(struct arena *a) +{ + a->next = a->begin; +} + + +/* + * Allocate new memory using arena + */ +void* arena_alloc(struct arena *a, size_t len) +{ + void *p = a->next; + a->next += len; + + if (a->next - a->begin >= a->cap) { + errno = ENOMEM; + return NULL; + } + + return p; +} + diff --git a/arena.h b/src/arena.h similarity index 64% rename from arena.h rename to src/arena.h index d07e761..7ba953e 100644 --- a/arena.h +++ b/src/arena.h @@ -1,12 +1,19 @@ +#ifndef ARENA_H +#define ARENA_H + + #include // ptrdiff_t struct arena { - void *start, - *next; + unsigned char *begin, + *next; ptrdiff_t cap; -} __attribute__((aligned(64))); +}; struct arena* arena_new(); void arena_reset(struct arena *a); void* arena_alloc(struct arena *a, size_t len); + + +#endif diff --git a/src/test_arena.c b/src/test_arena.c new file mode 100644 index 0000000..ba81508 --- /dev/null +++ b/src/test_arena.c @@ -0,0 +1,44 @@ + + + +// _start test_arena_alloc.c +#include "arena.h" +#include +#include +#include + +static struct arena *default_arena = NULL; + +int main() +{ + default_arena = arena_new(); + + if (default_arena == NULL) { + err(errno, "failed to allocate arena"); + } + + printf("\n%p\n", default_arena->next); + + char *ten_A = arena_alloc(default_arena, 11 * sizeof *ten_A); + char *ten_B = arena_alloc(default_arena, 11 * sizeof *ten_B); + char *ten_C = arena_alloc(default_arena, 11 * sizeof *ten_C); + + for (size_t i=0; i<10; ++i) { + ten_A[i] = 'A'; + ten_B[i] = 'B'; + ten_C[i] = 'C'; + } + + ten_A[10] = '\0'; + ten_B[10] = '\0'; + ten_C[10] = '\0'; + + printf("\n%s %s %s", ten_A, ten_B, ten_C); + printf("\n%p\n", default_arena->next); + + arena_reset(default_arena); + + printf("\n%p\n", default_arena->next); + + return 0; +} diff --git a/test_arena_alloc.c b/test_arena_alloc.c deleted file mode 100644 index cef10bc..0000000 --- a/test_arena_alloc.c +++ /dev/null @@ -1,31 +0,0 @@ - - - -// _start test_arena_alloc.c -#include "arena.h" -#include -#include -#include - -static struct arena *default_arena = NULL; - -int main() -{ - default_arena = arena_new(); - - if (default_arena == NULL) { - err(errno, "failed to allocate arena"); - } - - char *p = arena_alloc(default_arena, sizeof p * 11); - - for (size_t i=0; i<10; ++i) { - p[i] = 'A'; - } - - p[10] = '\0'; - - printf("%s", p); - - return 0; -}