#include #include #include #include struct List { enum { NODE, END } tag; union { struct { void* val; struct List* next; } node; struct { } end; } data; }; struct List End = { .tag = END, .data = {} }; #define ARENA_MAX 4000 struct Arena { uint8_t data[ARENA_MAX]; uintptr_t top; } ARENA = { .data = {0}, .top = 0 }; // returns a null pointer if the allocation could fail void* /* aligned top */ arena_allocate(uint8_t* val, size_t size, uintptr_t align) { uintptr_t addr = (uintptr_t)(&ARENA.data[0] + ARENA.top) ; uintptr_t m = addr % align; if (m != 0) ARENA.top += align - m; if (ARENA.top+size >= ARENA_MAX) return (void*)0; uint8_t* new_pos = ((&ARENA.data[0]) + ARENA.top); uint8_t* out_pos = new_pos; for (size_t i = 0; i < size; ++i) { *new_pos = *val; ++new_pos; ++val; } ARENA.top += size; return (void*)out_pos; } #define ARENA_ALLOC(val_ptr, type) (arena_allocate((uint8_t*)val_ptr, sizeof(type), alignof(type))) void print_float_list(struct List* float_list) { printf("\n["); for (struct List* float_list_ = float_list ; float_list_ != &End; float_list_ = float_list_->data.node.next ) { printf("%f", *(float*)float_list_->data.node.val); if ( float_list_->data.node.next->tag == NODE) printf(", "); } printf("]\n"); } int main() { float a[6] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; struct List* acc_list = &End; for (int i = 6; i!=0; ) { --i; void* ptr = ARENA_ALLOC(&a[i], float); struct List l = { .tag = NODE, .data = {.node = { .val = ptr, .next = acc_list }} }; acc_list = ARENA_ALLOC(&l, struct List); } print_float_list(acc_list); }