cbase 1.50.0
C/C++ Static Template
Loading...
Searching...
No Matches
Arena Allocator

Auto-committing linear allocator backed by OS virtual memory. More...

Classes

struct  MemArena
 A virtual memory-backed linear allocator. More...
struct  MemArenaTemp
 A temporary snapshot of an arena's state. More...

Macros

#define MEM_ARENA_ALIGNMENT   8
 The default byte alignment for memory pushed onto the arena.
#define PUSH_STRUCT(arena, type)
 Type-Safe Allocation Macros.
#define PUSH_ARRAY(arena, type, count)
 Pushes an array of structs of type T onto the arena.
#define PUSH_STRUCT_ALIGNED(arena, type, alignment)
 Pushes a struct with custom memory alignment.
#define PUSH_ARRAY_ALIGNED(arena, type, count, alignment)
 Pushes an array of structs with custom memory alignment.
#define PUSH_CSTR(arena, cstr)
 Copies a NUL-terminated C string into the arena.

Typedefs

typedef struct MemArena MemArena
 A virtual memory-backed linear allocator.
typedef struct MemArenaTemp MemArenaTemp
 A temporary snapshot of an arena's state.

Functions

MemArena mem_arena_create (usize reserve_size)
 Initializes a new virtual memory Arena.
void * mem_arena_push (MemArena *arena, usize size)
 Allocates bytes sequentially on the arena without zeroing.
void * mem_arena_push_zero (MemArena *arena, usize size)
 Allocates bytes and explicitly zero-initializes them.
void * mem_arena_push_aligned (MemArena *arena, usize size, usize alignment)
 Allocates bytes with a specific custom alignment.
char * mem_arena_push_cstr (MemArena *arena, const char *str, usize len)
 Copies a C string into the arena and appends a NUL terminator.
void mem_arena_pop_to (MemArena *arena, usize pos)
 Rewinds the arena's pointer to a specific offset.
void mem_arena_clear (MemArena *arena)
 Resets the arena pointer to zero, freeing all allocations in O(1).
void mem_arena_clear_and_decommit (MemArena *arena)
 Clears the arena and returns all committed physical RAM to the OS.
void mem_arena_release (MemArena *arena)
 Returns all virtual memory back to the operating system.
struct MemAllocator mem_arena_allocator (MemArena *arena)
 Wraps a MemArena in the generic MemAllocator interface.
MemArenaTemp mem_arena_temp_begin (MemArena *arena)
 Temporary Memory API.
void mem_arena_temp_end (MemArenaTemp temp)
 Restores the arena to the position saved in temp.

Detailed Description

Auto-committing linear allocator backed by OS virtual memory.

Macro Definition Documentation

◆ MEM_ARENA_ALIGNMENT

#define MEM_ARENA_ALIGNMENT   8

The default byte alignment for memory pushed onto the arena.

Definition at line 67 of file mem_arena.h.

◆ PUSH_ARRAY

#define PUSH_ARRAY ( arena,
type,
count )
Value:
((type *)mem_arena_push_zero((arena), sizeof(type) * (count)))
void * mem_arena_push_zero(MemArena *arena, usize size)
Allocates bytes and explicitly zero-initializes them.
Definition mem_arena.c:77

Pushes an array of structs of type T onto the arena.

Example:

MyStruct *array = PUSH_ARRAY(&arena, MyStruct, 100);
array[42].id = 1;
#define PUSH_ARRAY(arena, type, count)
Pushes an array of structs of type T onto the arena.
Definition mem_arena.h:343
MemArena mem_arena_create(usize reserve_size)
Initializes a new virtual memory Arena.
Definition mem_arena.c:48
#define GB(x)
Definition base_types.h:121
A virtual memory-backed linear allocator.
Definition mem_arena.h:70

Definition at line 343 of file mem_arena.h.

◆ PUSH_ARRAY_ALIGNED

#define PUSH_ARRAY_ALIGNED ( arena,
type,
count,
alignment )
Value:
((type *)mem_arena_push_aligned((arena), sizeof(type) * (count), (alignment)))
void * mem_arena_push_aligned(MemArena *arena, usize size, usize alignment)
Allocates bytes with a specific custom alignment.
Definition mem_arena.c:87

Pushes an array of structs with custom memory alignment.

Example:

// 32-byte aligned float array for AVX operations:
float *v = PUSH_ARRAY_ALIGNED(&arena, float, 64, 32);
// (usize)v % 32 == 0
#define PUSH_ARRAY_ALIGNED(arena, type, count, alignment)
Pushes an array of structs with custom memory alignment.
Definition mem_arena.h:366

Definition at line 366 of file mem_arena.h.

◆ PUSH_CSTR

#define PUSH_CSTR ( arena,
cstr )
Value:
(mem_arena_push_cstr((arena), (cstr), strlen(cstr)))
char * mem_arena_push_cstr(MemArena *arena, const char *str, usize len)
Copies a C string into the arena and appends a NUL terminator.
Definition mem_arena.c:121

Copies a NUL-terminated C string into the arena.

Convenience wrapper around mem_arena_push_cstr() that calls strlen for you. The result is always NUL-terminated and safe to pass to C string APIs.

Example:

const char *name = get_player_name();
char *owned = PUSH_CSTR(&arena, name);
// owned is now arena-owned and will not dangle if name changes
#define PUSH_CSTR(arena, cstr)
Copies a NUL-terminated C string into the arena.
Definition mem_arena.h:386
Parameters
arenaPointer to the MemArena.
cstrA NUL-terminated C string to copy.
Returns
Pointer to the arena-owned NUL-terminated copy, or NULL on OOM.

Definition at line 386 of file mem_arena.h.

◆ PUSH_STRUCT

#define PUSH_STRUCT ( arena,
type )
Value:
((type *)mem_arena_push_zero((arena), sizeof(type)))

Type-Safe Allocation Macros.

Pushes a struct of type T onto the arena.

Example:

MyStruct *data = PUSH_STRUCT(&arena, MyStruct);
data->id = 1;
#define PUSH_STRUCT(arena, type)
Type-Safe Allocation Macros.
Definition mem_arena.h:331

Definition at line 331 of file mem_arena.h.

◆ PUSH_STRUCT_ALIGNED

#define PUSH_STRUCT_ALIGNED ( arena,
type,
alignment )
Value:
((type *)mem_arena_push_aligned((arena), sizeof(type), (alignment)))

Pushes a struct with custom memory alignment.

Example:

// 16-byte aligned struct for SSE operations:
SimdVec4 *v = PUSH_STRUCT_ALIGNED(&arena, SimdVec4, 16);
#define PUSH_STRUCT_ALIGNED(arena, type, alignment)
Pushes a struct with custom memory alignment.
Definition mem_arena.h:354

Definition at line 354 of file mem_arena.h.

Function Documentation

◆ mem_arena_allocator()

struct MemAllocator mem_arena_allocator ( MemArena * arena)

Wraps a MemArena in the generic MemAllocator interface.

The returned MemAllocator holds a pointer to arena — the arena must outlive any use of the returned MemAllocator. Pass this to any API that takes a MemAllocator to use arena allocation without locking in the type.

Example:

StringBuilder sb = {0};
sb_append(&sb, &alloc, STR8("built with arena"));
struct MemAllocator mem_arena_allocator(MemArena *arena)
Wraps a MemArena in the generic MemAllocator interface.
Definition mem_arena.c:172
#define MB(x)
Definition base_types.h:120
static void sb_append(StringBuilder *sb, MemAllocator *alloc, String8 str)
Appends a String8 slice to the builder.
Definition str_builder.h:75
#define STR8(s)
Wraps a C string literal into a String8 at compile time.
An abstract allocator interface.
An allocator-agnostic string builder.
Definition str_builder.h:56
Parameters
arenaThe arena to bind.
Returns
A MemAllocator whose operations delegate to arena.

Definition at line 172 of file mem_arena.c.

Here is the call graph for this function:

◆ mem_arena_clear()

void mem_arena_clear ( MemArena * arena)

Resets the arena pointer to zero, freeing all allocations in O(1).

Physical RAM remains committed and warm for subsequent allocations — the next allocation after a clear is just as fast as before. This is the idiomatic per-frame reset pattern.

Example:

// Per-frame scratch pattern:
while (running) {
update(&scratch_arena);
render(&scratch_arena);
mem_arena_clear(&scratch_arena); // wipe everything, O(1)
}
void mem_arena_clear(MemArena *arena)
Resets the arena pointer to zero, freeing all allocations in O(1).
Definition mem_arena.c:105
Parameters
arenaThe arena to clear.

Definition at line 105 of file mem_arena.c.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mem_arena_clear_and_decommit()

void mem_arena_clear_and_decommit ( MemArena * arena)

Clears the arena and returns all committed physical RAM to the OS.

Use instead of mem_arena_clear() when the arena held a large one-off allocation and you want those physical pages back. Subsequent allocations will re-commit RAM on demand as normal.

Example:

// Level load scratch: free the level data AND return the pages:
load_level(&level_scratch);
process_level_data(&level_scratch);
void mem_arena_clear_and_decommit(MemArena *arena)
Clears the arena and returns all committed physical RAM to the OS.
Definition mem_arena.c:111
Parameters
arenaThe arena to reset and decommit.

Definition at line 111 of file mem_arena.c.

Here is the call graph for this function:

◆ mem_arena_create()

MemArena mem_arena_create ( usize reserve_size)

Initializes a new virtual memory Arena.

Example:

// arena.base != NULL, arena.pos == 0, arena.commit == 0
// No physical RAM consumed until the first allocation.
Parameters
reserve_sizeThe total virtual address space to reserve (e.g., GB(1)).
Returns
An initialized MemArena. On failure, .base will be NULL.

Definition at line 48 of file mem_arena.c.

Here is the call graph for this function:

◆ mem_arena_pop_to()

void mem_arena_pop_to ( MemArena * arena,
usize pos )

Rewinds the arena's pointer to a specific offset.

All memory at or above pos is considered freed. Committed physical RAM is not returned to the OS. Prefer MemArenaTemp for scoped rollbacks.

Example:

usize checkpoint = arena.pos;
int *tmp = PUSH_ARRAY(&arena, int, 1024);
// ... use tmp ...
mem_arena_pop_to(&arena, checkpoint); // tmp is gone
void mem_arena_pop_to(MemArena *arena, usize pos)
Rewinds the arena's pointer to a specific offset.
Definition mem_arena.c:97
size_t usize
Definition base_types.h:68
Parameters
arenaThe arena to rewind.
posThe offset to pop back to (must be <= arena->pos in debug builds).

Definition at line 97 of file mem_arena.c.

Here is the caller graph for this function:

◆ mem_arena_push()

void * mem_arena_push ( MemArena * arena,
usize size )

Allocates bytes sequentially on the arena without zeroing.

Prefer mem_arena_push_zero() unless you are about to overwrite the entire allocation. Physical RAM is committed in 64 KB chunks as needed.

Example:

// Read a file directly into the arena without a zero-init pass:
char *buf = (char *)mem_arena_push(&arena, file_size);
fread(buf, 1, file_size, fp);
void * mem_arena_push(MemArena *arena, usize size)
Allocates bytes sequentially on the arena without zeroing.
Definition mem_arena.c:71
Parameters
arenaThe arena to allocate from.
sizeThe number of bytes to allocate.
Returns
A pointer to the aligned memory block, or NULL on OOM.

Definition at line 71 of file mem_arena.c.

◆ mem_arena_push_aligned()

void * mem_arena_push_aligned ( MemArena * arena,
usize size,
usize alignment )

Allocates bytes with a specific custom alignment.

Use when the default 8-byte alignment is insufficient, e.g. for SIMD data that requires 16 or 32-byte alignment.

Example:

// 64 floats aligned to 32 bytes for AVX operations:
float *v = (float *)mem_arena_push_aligned(&arena, sizeof(float) * 64, 32);
// (usize)v % 32 == 0 guaranteed
Parameters
arenaThe arena to allocate from.
sizeThe number of bytes to allocate.
alignmentThe alignment boundary (must be a power of 2).
Returns
A pointer to the zero-initialized, aligned memory block, or NULL on OOM.

Definition at line 87 of file mem_arena.c.

◆ mem_arena_push_cstr()

char * mem_arena_push_cstr ( MemArena * arena,
const char * str,
usize len )

Copies a C string into the arena and appends a NUL terminator.

The resulting buffer is always safe to pass to any C string API. Use the PUSH_CSTR macro as a convenience wrapper that calls strlen for you.

Example:

const char *src = "hello";
char *copy = mem_arena_push_cstr(&arena, src, strlen(src));
// copy is NUL-terminated and arena-owned
Parameters
arenaThe arena to allocate from.
strThe source string (does not need to be NUL-terminated).
lenNumber of characters to copy (excluding the NUL terminator).
Returns
A NUL-terminated arena-owned copy, or NULL on OOM.

Definition at line 121 of file mem_arena.c.

Here is the call graph for this function:

◆ mem_arena_push_zero()

void * mem_arena_push_zero ( MemArena * arena,
usize size )

Allocates bytes and explicitly zero-initializes them.

This is the preferred push variant. Use mem_arena_push() only when you are certain you will overwrite every byte before reading it.

Example:

// Zero-initialized struct — safe to read any field immediately:
Player *p = (Player *)mem_arena_push_zero(&arena, sizeof(Player));
p->health = 100;
Parameters
arenaThe arena to allocate from.
sizeThe number of bytes to allocate.
Returns
A pointer to the zeroed memory block, or NULL on OOM.

Definition at line 77 of file mem_arena.c.

Here is the caller graph for this function:

◆ mem_arena_release()

void mem_arena_release ( MemArena * arena)

Returns all virtual memory back to the operating system.

Every pointer previously returned by mem_arena_push*() becomes invalid. Call this when the arena will no longer be used.

Example:

// ... use arena ...
// arena.base == NULL, arena.reserve == 0
void mem_arena_release(MemArena *arena)
Returns all virtual memory back to the operating system.
Definition mem_arena.c:59
Parameters
arenaThe arena to release.

Definition at line 59 of file mem_arena.c.

Here is the call graph for this function:

◆ mem_arena_temp_begin()

MemArenaTemp mem_arena_temp_begin ( MemArena * arena)

Temporary Memory API.

Saves the current arena position as a rewind checkpoint.

Example:

u8 *scratch = PUSH_ARRAY(&arena, u8, KB(4));
// ... build something temporary ...
mem_arena_temp_end(tmp); // arena snaps back, scratch is gone
uint8_t u8
Definition base_types.h:46
void mem_arena_temp_end(MemArenaTemp temp)
Restores the arena to the position saved in temp.
Definition mem_arena.c:141
MemArenaTemp mem_arena_temp_begin(MemArena *arena)
Temporary Memory API.
Definition mem_arena.c:132
#define KB(x)
Definition base_types.h:119
A temporary snapshot of an arena's state.
Definition mem_arena.h:78
Parameters
arenaThe arena to checkpoint.
Returns
A MemArenaTemp holding the arena pointer and the saved position.

Definition at line 132 of file mem_arena.c.

◆ mem_arena_temp_end()

void mem_arena_temp_end ( MemArenaTemp temp)

Restores the arena to the position saved in temp.

All allocations made after the corresponding mem_arena_temp_begin() are effectively freed. Physical RAM remains committed and reusable.

Parameters
tempThe checkpoint returned by mem_arena_temp_begin().

Definition at line 141 of file mem_arena.c.

Here is the call graph for this function: