crazy arena implementation

This commit is contained in:
Judah Caruso 2026-02-18 23:12:47 -07:00
parent 17e458b4e7
commit df60b5f76f
4 changed files with 113 additions and 22 deletions

View file

@ -1,9 +1,8 @@
-I./src -Isrc
-I./thirdparty/ -Ithirdparty/
-I./thirdparty/blocksruntime/BlocksRuntime/ -Ithirdparty/blocksruntime/BlocksRuntime/
-I./thirdparty/blocksruntime/ -Ithirdparty/blocksruntime/
--std=c2x --std=c2x
-fblocks -fblocks
-xobjective-c -xobjective-c
-DPLATFORM_MACOS -DCHANGE_THESE_LINES_IF_YOURE_ON_A_DIFFERENT_PLATFORM -DPLATFORM_MACOS -DCHANGE_THESE_LINES_IF_YOURE_ON_A_DIFFERENT_PLATFORM

73
src/arena.c Normal file
View file

@ -0,0 +1,73 @@
#include <string.h>
#include <stdlib.h>
typedef enum { arena__alloc, arena__reset, arena__release } arena__action;
typedef void* (^Arena)(arena__action, usize, usize, usize*, const char*, sreg);
#define arena_new(A, T) cast(T*, A(arena__alloc, sizeof(T), alignof(T), 0, __FILE__, __LINE__))
#define arena_reset(A) A(arena__reset, 0, 0, 0, __FILE__, __LINE__)
#define arena_release(A) A(arena__release, 0, 0, 0, __FILE__, __LINE__)
// just a nice macro to make these easier to write
#define func(a1, a2, a3, a4, a5, a6) ^void* (arena__action a1, usize a2, usize a3, usize* a4, const char* a5, sreg a6)
static Arena
Static(u8* data, usize count) {
memset(data, 0, count);
capture usize offset = 0;
return closure(func(action, size, align, _1, _2, _3) {
switch (action) {
default: {
} break;
case arena__alloc: {
offset = (offset + align - 1) & ~(align - 1);
if (offset + size > count) return 0;
void* ptr = data + offset;
offset += size;
return ptr;
} break;
case arena__reset: {
offset = 0;
} break;
}
return 0;
});
}
static Arena
Linear(usize max_memory) {
void* ptr = malloc(max_memory);
Arena backing = Static(ptr, max_memory);
return closure(func(action, size, align, savepoint, file, line) {
if (action == arena__release) {
free(ptr);
return 0;
}
return backing(action, size, align, savepoint, file, line);
});
}
static Arena
Logger(Arena arena) {
return closure(func(action, size, align, savepoint, file, line) {
char* action_str = "unknown";
switch (action) {
case arena__alloc: action_str = "alloc"; break;
case arena__reset: action_str = "reset"; break;
case arena__release: action_str = "release"; break;
}
printf("[ARENA] %s:%zd: %s (%zu, %zu)\n", file, line, action_str, size, align);
return arena(action, size, align, savepoint, file, line);
});
}
#undef func

View file

@ -31,14 +31,15 @@ typedef int64_t s64;
typedef float f32; typedef float f32;
typedef double f64; typedef double f64;
typedef intptr_t intptr; typedef uintptr_t uptr;
typedef uintptr_t uintptr; typedef intptr_t sptr;
typedef uptr ureg;
typedef sptr sreg;
typedef size_t usize; typedef size_t usize;
typedef ptrdiff_t ssize; typedef ptrdiff_t ssize;
typedef int64_t sint;
typedef uint64_t uint;
// Thanks AZMR // Thanks AZMR
#define cast(to_type, expr) ((to_type)(expr)) #define cast(to_type, expr) ((to_type)(expr))

View file

@ -1,5 +1,6 @@
#include <stdio.h> #include <stdio.h>
#include "base.c" #include "base.c"
#include "arena.c"
#define SOKOL_IMPL #define SOKOL_IMPL
@ -52,19 +53,36 @@ init(void) {
x += 1; x += 1;
}); });
s32 i = -10243; printf("x = %d (before)\n", x);
scope_exit { for (ureg i = 0; i < 10; i += 1) {
printf("it works %d!\n", i); inc();
}; }
printf("x = %d (after)\n", x);
printf("x = %d\n", x); auto arena = Logger(Linear(1024 * 1024));
inc(); scope_exit { arena_release(arena); };
inc();
inc(); sreg* a = arena_new(arena, sreg);
inc(); sreg* b = arena_new(arena, sreg);
inc(); sreg* c = arena_new(arena, sreg);
inc();
printf("x = %d\n", x); *a = 1024;
*b = 2048;
*c = 4096;
printf("%zu (%p)\n", *a, a);
printf("%zu (%p)\n", *b, b);
printf("%zu (%p)\n", *c, c);
arena_reset(arena);
c = arena_new(arena, sreg);
b = arena_new(arena, sreg);
a = arena_new(arena, sreg);
printf("%zu (%p)\n", *a, a);
printf("%zu (%p)\n", *b, b);
printf("%zu (%p)\n", *c, c);
} }
static void static void