diff options
Diffstat (limited to 'src/bump_alloc.h')
| -rw-r--r-- | src/bump_alloc.h | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/bump_alloc.h b/src/bump_alloc.h new file mode 100644 index 0000000..bc9cbac --- /dev/null +++ b/src/bump_alloc.h @@ -0,0 +1,54 @@ +#include <assert.h> +#include <stddef.h> /* NULL, size_t */ +#include <stdint.h> /* uintptr_t */ + +#ifndef MEMSIZE +#define MEMSIZE 1024*4*1024*1024l +#endif + +#define unlikely(x) __builtin_expect((x),0) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uintptr_t end = 0; + uintptr_t ptr = 0; +} bumpptr_t; + +__thread bumpptr_t* tsd = NULL; + +inline void init_tsd() { + void* mem_start = mmap(NULL, MEMSIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + if(mem_start == MAP_FAILED) { + perror("mmap"); + return NULL; + } + tsd = (bumpptr_t*)mem_start; + tsd->ptr = (uintptr_t)mem_start + sizeof(bumpptr_t); + tsd->end = (uintptr_t)mem_start + MEMSIZE; +} + +inline void* bump_up(size_t size, size_t align) { + assert(align % 2 == 0); + + if (unlikely(tsd == NULL)) { + init_tsd(); + } + + // align ptr; + uintptr_t aligned = (tsd->ptr + align - 1) & ~(align - 1); + + uintptr_t new_ptr = aligned + size; + if (new_ptr > mem_end) + return NULL; + else { + tsd->ptr = new_ptr; + return (void*)aligned; + } +} + +#ifdef __cplusplus +} +#endif |
