Commit: 15ca2d03fb84519df736079d3686fc1cc8ddfda3
Parent: beda44ae53194d3ff72eae4d43397b11cf89c36c
Author: Randy Palamar
Date: Sun, 4 Jan 2026 10:44:51 -0700
util: arena_alloc parameters
Pushing without zeroing will be important for upcoming code. It
will always be statically known so this will never harm
performance.
Diffstat:
4 files changed, 42 insertions(+), 25 deletions(-)
diff --git a/main_linux.c b/main_linux.c
@@ -39,7 +39,7 @@ dispatch_file_watch_events(void)
{
OSLinux_FileWatchDirectoryList *fwctx = &os_linux_context.file_watch_list;
Arena arena = os_linux_context.arena;
- u8 *mem = arena_alloc(&arena, 4096, 16, 1);
+ u8 *mem = arena_alloc(&arena, .size = 4096, .align = 16);
Stream path = stream_alloc(&arena, 256);
struct inotify_event *event;
diff --git a/os_win32.c b/os_win32.c
@@ -425,7 +425,7 @@ function OS_ADD_FILE_WATCH_FN(os_add_file_watch)
dir->event.context = (iptr)dir;
CreateIoCompletionPort(dir->handle, os_w32_context.io_completion_handle, (uptr)&dir->event, 0);
- dir->buffer = arena_alloc(&os_w32_context.arena, OSW32_FileWatchDirectoryBufferSize, 8, 1);
+ dir->buffer = arena_alloc(&os_w32_context.arena, .size = OSW32_FileWatchDirectoryBufferSize);
ReadDirectoryChangesW(dir->handle, dir->buffer, OSW32_FileWatchDirectoryBufferSize, 0,
FILE_NOTIFY_CHANGE_LAST_WRITE, 0, &dir->overlapped, 0);
}
diff --git a/ui.c b/ui.c
@@ -1049,8 +1049,8 @@ add_variable(BeamformerUI *ui, Variable *group, Arena *arena, s8 name, u32 flags
VariableType type, Font font)
{
Variable *result = SLLPopFreelist(ui->variable_freelist);
- if (result) zero_struct(result);
- else result = push_struct(arena, Variable);
+ if (!result) result = push_struct_no_zero(arena, Variable);
+ zero_struct(result);
return fill_variable(result, group, name, flags, type, font);
}
@@ -1349,8 +1349,8 @@ function BeamformerFrameView *
ui_beamformer_frame_view_new(BeamformerUI *ui, Arena *arena)
{
BeamformerFrameView *result = SLLPopFreelist(ui->view_freelist);
- if (result) zero_struct(result);
- else result = push_struct(arena, typeof(*result));
+ if (!result) result = push_struct_no_zero(arena, typeof(*result));
+ zero_struct(result);
DLLPushDown(result, ui->views);
return result;
}
diff --git a/util.c b/util.c
@@ -1,4 +1,10 @@
/* See LICENSE for license details. */
+#if COMPILER_CLANG
+ #pragma GCC diagnostic ignored "-Winitializer-overrides"
+#elif COMPILER_GCC
+ #pragma GCC diagnostic ignored "-Woverride-init"
+#endif
+
#define zero_struct(s) mem_clear(s, 0, sizeof(*s))
function void *
mem_clear(void *restrict p_, u8 c, iz size)
@@ -72,34 +78,45 @@ arena_pop(Arena *a, iz length)
a->beg -= length;
}
-#define push_array(a, t, n) (t *)arena_alloc(a, sizeof(t), _Alignof(t), n)
-#define push_struct(a, t) (t *)arena_alloc(a, sizeof(t), _Alignof(t), 1)
+typedef enum {
+ ArenaAllocateFlags_NoZero = 1 << 0,
+} ArenaAllocateFlags;
+
+typedef struct {
+ iz size;
+ uz align;
+ iz count;
+ ArenaAllocateFlags flags;
+} ArenaAllocateInfo;
+
+#define arena_alloc(a, ...) arena_alloc_(a, (ArenaAllocateInfo){.align = 8, .count = 1, ##__VA_ARGS__})
+#define push_array(a, t, n) (t *)arena_alloc(a, .size = sizeof(t), .align = alignof(t), .count = n)
+#define push_array_no_zero(a, t, n) (t *)arena_alloc(a, .size = sizeof(t), .align = alignof(t), .count = n, .flags = ArenaAllocateFlags_NoZero)
+#define push_struct(a, t) push_array(a, t, 1)
+#define push_struct_no_zero(a, t) push_array_no_zero(a, t, 1)
+
function void *
-arena_alloc(Arena *a, iz len, uz align, iz count)
+arena_alloc_(Arena *a, ArenaAllocateInfo info)
{
void *result = 0;
if (a->beg) {
- u8 *start = arena_aligned_start(*a, align);
+ u8 *start = arena_aligned_start(*a, info.align);
iz available = a->end - start;
- assert((available >= 0 && count <= available / len));
- asan_unpoison_region(start, count * len);
- a->beg = start + count * len;
- /* TODO: Performance? */
- result = mem_clear(start, 0, count * len);
+ assert((available >= 0 && info.count <= available / info.size));
+ asan_unpoison_region(start, info.count * info.size);
+ a->beg = start + info.count * info.size;
+ result = start;
+ if ((info.flags & ArenaAllocateFlags_NoZero) == 0)
+ result = mem_clear(start, 0, info.count * info.size);
}
return result;
}
function Arena
-sub_arena(Arena *a, iz len, uz align)
+sub_arena(Arena *a, iz size, uz align)
{
- Arena result = {0};
-
- uz padding = -(uintptr_t)a->beg & (align - 1);
- result.beg = a->beg + padding;
- result.end = result.beg + len;
- arena_commit(a, len + (iz)padding);
-
+ Arena result = {.beg = arena_alloc(a, .size = size, .align = align, .flags = ArenaAllocateFlags_NoZero)};
+ result.end = result.beg + size;
return result;
}
@@ -161,14 +178,14 @@ da_reserve_(Arena *a, void *data, iz *capacity, iz needed, uz align, iz size)
/* NOTE(rnp): handle both 0 initialized DAs and DAs that need to be moved (they started
* on the stack or someone allocated something in the middle of the arena during usage) */
if (!data || a->beg != (u8 *)data + cap * size) {
- void *copy = arena_alloc(a, size, align, cap);
+ void *copy = arena_alloc(a, .size = size, .align = align, .count = cap);
if (data) mem_copy(copy, data, (uz)(cap * size));
data = copy;
}
if (!cap) cap = DA_INITIAL_CAP;
while (cap < needed) cap *= 2;
- arena_alloc(a, size, align, cap - *capacity);
+ arena_alloc(a, .size = size, .align = align, .count = cap - *capacity);
*capacity = cap;
return data;
}