add missing arena.h

This commit is contained in:
Richard Thier 2024-09-07 21:25:03 +02:00
parent 119c3d1af7
commit c88bd10b73
3 changed files with 112 additions and 3 deletions

103
arena.h Normal file
View File

@ -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 <stddef.h>
#include <string.h>
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 <sys/mman.h>
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 */

View File

@ -6,7 +6,10 @@
#include<vector> #include<vector>
#include<stdlib.h> #include<stdlib.h>
#include"TurboList.hpp" #include"TurboList.hpp"
#include"turbolist.h"
#define TLT int
#include "turbolist.h"
#include"arena.h" #include"arena.h"
// #define PRINT_DBG // #define PRINT_DBG

View File

@ -1,6 +1,9 @@
#ifndef TURBO_LIST_H #ifndef TURBO_LIST_H
#define TURBO_LIST_H #define TURBO_LIST_H
#ifndef TL_NO_CSTDLIB
#include<cstdlib>
#endif /* TL_NO_CSTDLIB */
#include<stdint.h> #include<stdint.h>
#include<assert.h> #include<assert.h>
@ -56,11 +59,11 @@ static inline turbolist turbolist_create_adv(void* (*malloc_like)(size_t size),
return tl; return tl;
} }
#ifndef NO_CSTDLIB #ifndef TL_NO_CSTDLIB
static inline turbolist turbolist_create() { static inline turbolist turbolist_create() {
return turbolist_create_adv(malloc, free, 0, 16); return turbolist_create_adv(malloc, free, 0, 16);
} }
#endif /* NO_CSTDLIB */ #endif /* TL_NO_CSTDLIB */
static inline void turbolist_delete(turbolist *tl) { static inline void turbolist_delete(turbolist *tl) {
if(tl->nex) tl->free(tl->nex); if(tl->nex) tl->free(tl->nex);