cbase 1.46.11
C/C++ Static Template
Loading...
Searching...
No Matches
mem_arena.c
Go to the documentation of this file.
1
7
8#include "memory/mem_arena.h"
9#include "memory/mem_os.h"
10
22static void *
23arena_push_internal(Arena *arena, usize size, usize alignment)
24{
25 ASSERT(IS_POW2_OR_ZERO(alignment) && "alignment must be a power of 2");
26
27 // Align the current position up to the requested boundary.
28 usize current_pos = ALIGN_UP_POW2(arena->pos, alignment);
29 usize next_pos = current_pos + size;
30
31 // Guard: prevent overflowing past the total reserved capacity.
32 if (next_pos > arena->cap) {
33 ASSERT(0 && "Arena OOM: allocation exceeds reserved capacity");
34 return NULL;
35 }
36
37 // Commit more physical RAM if the allocation would exceed what we have.
38 if (next_pos > arena->cmt) {
39 // Round the required commit up to our chunk granularity.
40 usize needed = next_pos - arena->cmt;
41 usize cmt_size = ALIGN_UP_POW2(needed, ARENA_COMMIT_SIZE);
42 // Clamp so we never try to commit past the reservation ceiling.
43 usize cmt_clamped = MIN(cmt_size, arena->cap - arena->cmt);
44
45 b32 ok = os_mem_commit(arena->base + arena->cmt, cmt_clamped);
46 if (!ok) {
47 ASSERT(0 && "Arena OOM: OS refused to commit physical RAM");
48 return NULL;
49 }
50
51 arena->cmt += cmt_clamped;
52 }
53
54 void *result = arena->base + current_pos;
55 arena->pos = next_pos;
56 return result;
57}
58
60arena_create(usize reserve_size)
61{
62 Arena arena = {0};
63 arena.base = (u8 *)os_mem_reserve(reserve_size);
64 if (arena.base != NULL) {
65 arena.cap = reserve_size;
66 }
67 return arena;
68}
69
70void
72{
73 if (arena->base != NULL) {
74 os_mem_release(arena->base, arena->cap);
75 arena->base = NULL;
76 arena->cap = 0;
77 arena->pos = 0;
78 arena->cmt = 0;
79 }
80}
81
82void *
83arena_push(Arena *arena, usize size)
84{
85 return arena_push_internal(arena, size, ARENA_DEFAULT_ALIGN);
86}
87
88void *
90{
91 void *result = arena_push_internal(arena, size, ARENA_DEFAULT_ALIGN);
92 if (result != NULL) {
93 MEM_ZERO(result, size);
94 }
95 return result;
96}
97
98void *
99arena_push_aligned(Arena *arena, usize size, usize alignment)
100{
101 void *result = arena_push_internal(arena, size, alignment);
102 if (result != NULL) {
103 MEM_ZERO(result, size);
104 }
105 return result;
106}
107
108void
110{
111 // Clamp so that a pos > arena->pos cannot accidentally advance the offset.
112 usize clamped = MIN(pos, arena->pos);
113 arena->pos = clamped;
114}
115
116void
118{
119 arena_pop_to(arena, 0);
120}
121
124{
125 ArenaTemp temp;
126 temp.arena = arena;
127 temp.pos = arena->pos;
128 return temp;
129}
130
131void
133{
134 arena_pop_to(temp.arena, temp.pos);
135}
#define IS_POW2_OR_ZERO(x)
Checks if a given integer is a power of 2 (or zero).
#define ALIGN_UP_POW2(x, p)
Aligns a value UP to the nearest power of 2.
#define ARENA_DEFAULT_ALIGN
The default alignment for all arena_push() allocations (8 bytes).
Definition mem_arena.h:66
Arena arena_create(usize reserve_size)
Creates and initializes a new arena, reserving virtual address space.
Definition mem_arena.c:60
void arena_release(Arena *arena)
Releases the entire arena back to the OS, invalidating all pointers into it.
Definition mem_arena.c:71
void arena_temp_end(ArenaTemp temp)
Restores the arena to the position saved in temp.
Definition mem_arena.c:132
#define ARENA_COMMIT_SIZE
The granularity at which physical RAM is committed from the OS (64 KB).
Definition mem_arena.h:75
void arena_clear(Arena *arena)
Resets the arena to empty by setting pos back to 0.
Definition mem_arena.c:117
void * arena_push(Arena *arena, usize size)
Allocates size bytes from the arena, aligned to ARENA_DEFAULT_ALIGN.
Definition mem_arena.c:83
void arena_pop_to(Arena *arena, usize pos)
Rolls the arena back to a specific byte offset.
Definition mem_arena.c:109
ArenaTemp arena_temp_begin(Arena *arena)
Saves the current arena position as a rewind checkpoint.
Definition mem_arena.c:123
void * arena_push_aligned(Arena *arena, usize size, usize alignment)
Allocates size bytes from the arena with an explicit power-of-2 alignment.
Definition mem_arena.c:99
void * arena_push_zero(Arena *arena, usize size)
Allocates size bytes from the arena, zeroed, aligned to ARENA_DEFAULT_ALIGN.
Definition mem_arena.c:89
uint8_t u8
Definition base_types.h:22
#define ASSERT(expr)
Standard runtime assertion. Triggers a debug break on failure.
void * os_mem_reserve(usize size)
Reserves a block of virtual address space.
Definition mem_os.c:18
b32 os_mem_commit(void *ptr, usize size)
Commits physical RAM to a previously reserved address range.
Definition mem_os.c:29
void os_mem_release(void *ptr, usize size)
Releases a reserved virtual address range entirely back to the OS.
Definition mem_os.c:50
#define MEM_ZERO(ptr, size)
Wraps memset to explicitly write 0s to a block of memory.
size_t usize
Definition base_types.h:43
#define MIN(a, b)
Returns the minimum of two values (Standard C fallback).
int32_t b32
Definition base_types.h:75
static void * arena_push_internal(Arena *arena, usize size, usize alignment)
Core allocation primitive with a caller-specified alignment.
Definition mem_arena.c:23
High-performance Virtual Memory Linear (Arena) Allocator.
Operating System virtual memory wrappers.
Represents a linear memory arena backed by OS virtual memory.
Definition mem_arena.h:83
usize cap
Definition mem_arena.h:85
u8 * base
Definition mem_arena.h:84
usize pos
Definition mem_arena.h:86
usize cmt
Definition mem_arena.h:87
A saved checkpoint into an arena, used for scoped temporary allocations.
Definition mem_arena.h:105
usize pos
Definition mem_arena.h:107
Arena * arena
Definition mem_arena.h:106