From c88bd10b73b4bea456a3b19a135de061a85b6060 Mon Sep 17 00:00:00 2001 From: Richard Thier Date: Sat, 7 Sep 2024 21:25:03 +0200 Subject: [PATCH] add missing arena.h --- arena.h | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ main.cpp | 5 ++- turbolist.h | 7 +++- 3 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 arena.h diff --git a/arena.h b/arena.h new file mode 100644 index 0000000..f71396a --- /dev/null +++ b/arena.h @@ -0,0 +1,103 @@ +// Gradual-commit arena demonstration +// This is free and unencumbered software released into the public domain. +/* Usage: + * + * arena a = newarena((ptrdiff_t)1 << 33); + * if (!alloc(a, size, align, count)) { + * break; + * } + * total += size * count; + */ +#ifndef ARENA_H +#define ARENA_H + +#include +#include + +static void *os_reserve(ptrdiff_t); +static char os_commit(void *, ptrdiff_t); + +#define ARENA_PAGESIZE ((ptrdiff_t)1<<26) + +typedef struct { + char *begin; + char *commit; + char *end; +} arena; + +static arena newarena(ptrdiff_t cap) +{ + arena a = {0}; + cap += -cap & (ARENA_PAGESIZE - 1); + a.begin = a.commit = a.end = (char*) os_reserve(cap); + if (a.begin) { + a.end += cap; + } + return a; +} + +static void *alloc(arena *a, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count) +{ + ptrdiff_t padding = -(size_t)a->begin & (align - 1); + ptrdiff_t committed = a->commit - a->begin; + if (count > (committed-padding)/size) { + ptrdiff_t reserved = a->end - a->begin; + if (count > (reserved-padding)/size) { + return 0; + } + + ptrdiff_t needed = size*count + padding - committed; + needed += -needed & (ARENA_PAGESIZE - 1); + if (!os_commit(a->commit, needed)) { + return 0; + } + a->commit += needed; + } + + void *ptr = a->begin + padding; + a->begin += padding + size*count; + + // Change to this instead if you want zero-inited (but this gets slow with many arenas) + //return memset(ptr, 0, size*count); + return ptr; +} + +#ifdef _WIN32 +// $ cc -g3 -nostartfiles -o arena.exe arena.c +// $ cl /Z7 arena.c /link /subsystem:console kernel32.lib libvcruntime.lib +#define W32(r) __declspec(dllimport) r __stdcall +W32(void) ExitProcess(int); +W32(void *) VirtualAlloc(void *, ptrdiff_t, int, int); + +#define MEM_COMMIT 0x1000 +#define MEM_RESERVE 0x2000 +#define PAGE_NOACCESS 0x0001 +#define PAGE_READWRITE 0x0004 + +static void *os_reserve(ptrdiff_t cap) +{ + return VirtualAlloc(0, cap, MEM_RESERVE, PAGE_NOACCESS); +} + +static char os_commit(void *ptr, ptrdiff_t len) +{ + return VirtualAlloc(ptr, len, MEM_COMMIT, PAGE_READWRITE); +} + +#else // POSIX +// $ cc -g3 -o arena arena.c +#include + +static void *os_reserve(ptrdiff_t cap) +{ + void *r = mmap(0, cap, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0); + return r==MAP_FAILED ? 0 : r; +} + +static char os_commit(void *ptr, ptrdiff_t len) +{ + return !mprotect(ptr, len, PROT_READ|PROT_WRITE); +} +#endif // POSIX + +#endif /* ARENA_H */ diff --git a/main.cpp b/main.cpp index 3d79b10..8a302c7 100644 --- a/main.cpp +++ b/main.cpp @@ -6,7 +6,10 @@ #include #include #include"TurboList.hpp" -#include"turbolist.h" + +#define TLT int +#include "turbolist.h" + #include"arena.h" // #define PRINT_DBG diff --git a/turbolist.h b/turbolist.h index 92d29eb..2c523f8 100644 --- a/turbolist.h +++ b/turbolist.h @@ -1,6 +1,9 @@ #ifndef TURBO_LIST_H #define TURBO_LIST_H +#ifndef TL_NO_CSTDLIB +#include +#endif /* TL_NO_CSTDLIB */ #include #include @@ -56,11 +59,11 @@ static inline turbolist turbolist_create_adv(void* (*malloc_like)(size_t size), return tl; } -#ifndef NO_CSTDLIB +#ifndef TL_NO_CSTDLIB static inline turbolist turbolist_create() { return turbolist_create_adv(malloc, free, 0, 16); } -#endif /* NO_CSTDLIB */ +#endif /* TL_NO_CSTDLIB */ static inline void turbolist_delete(turbolist *tl) { if(tl->nex) tl->free(tl->nex);