cbase 1.46.11
C/C++ Static Template
Loading...
Searching...
No Matches
test_memory.c
2#include "memory/mem_arena.h"
3
4TEST_CASE(arena_allocation)
5{
6 Arena a = arena_create(GB(1));
7 EXPECT(a.base != NULL);
8 EXPECT(a.cap == GB(1));
9 EXPECT(a.pos == 0);
10 EXPECT(a.cmt == 0);
11
12 // Push a single int. arena_push_zero aligns to ARENA_DEFAULT_ALIGN (8),
13 // so pos advances to sizeof(int) == 4, not 8 (alignment affects the
14 // *start* of the next allocation, not the current one).
15 int *num = PUSH_STRUCT(&a, int);
16 *num = 42;
17 EXPECT(a.pos == 4);
18 EXPECT(*num == 42);
19
20 // Physical RAM should now be committed in at least one 64 KB chunk.
22
23 // Push an array and verify zero-initialization.
24 int *arr = PUSH_ARRAY(&a, int, 10);
25 EXPECT(arr[0] == 0);
26 EXPECT(arr[9] == 0);
27
28 // pos was 4 after the int. Next alloc aligns up to 8, then adds 10*4=40 -> pos == 48.
29 EXPECT(a.pos == 48);
30
31 arena_clear(&a);
32 EXPECT(a.pos == 0); // pos resets; committed RAM stays mapped.
33
34 arena_release(&a);
35 EXPECT(a.base == NULL);
36 EXPECT(a.cap == 0);
37}
38
39TEST_CASE(arena_aligned_push)
40{
41 Arena a = arena_create(MB(1));
42 EXPECT(a.base != NULL);
43
44 // Bump pos to a non-aligned starting point by pushing 1 byte.
45 u8 *byte = (u8 *)arena_push(&a, 1);
46 EXPECT(byte != NULL);
47
48 // Push with 16-byte alignment (e.g., for SIMD).
49 float *simd = PUSH_ARRAY_ALIGNED(&a, float, 4, 16);
50 EXPECT(simd != NULL);
51 EXPECT(((usize)simd & 15) == 0); // pointer must be 16-byte aligned
52 EXPECT(simd[0] == 0.0f); // must be zeroed
53
54 arena_release(&a);
55}
56
57TEST_CASE(arena_temp)
58{
59 Arena a = arena_create(MB(1));
60 EXPECT(a.base != NULL);
61
62 int *persistent = PUSH_STRUCT(&a, int);
63 *persistent = 99;
64 usize pos_before = a.pos;
65
67
68 u8 *scratch = PUSH_ARRAY(&a, u8, 512);
69 EXPECT(scratch != NULL);
70 EXPECT(a.pos > pos_before);
71
72 arena_temp_end(tmp);
73 EXPECT(a.pos == pos_before); // must snap back
74 EXPECT(*persistent == 99); // persistent alloc survives
75
76 arena_release(&a);
77}
78
79TEST_CASE(arena_allocator_interface)
80{
81 Arena a = arena_create(MB(1));
82 Allocator ally = arena_allocator(&a);
83
84 int *val = (int *)allocator_alloc(&ally, sizeof(int));
85 EXPECT(val != NULL);
86 EXPECT(*val == 0); // zero-initialized
87 *val = 7;
88 EXPECT(*val == 7);
89
90 allocator_free(&ally, val, sizeof(int)); // no-op, must not crash
91
92 usize old_size = sizeof(int) * 4;
93 usize new_size = sizeof(int) * 8;
94 int *arr = (int *)allocator_alloc(&ally, old_size);
95 arr[0] = 1;
96 arr[3] = 4;
97
98 int *grown = (int *)allocator_realloc(&ally, arr, old_size, new_size);
99 EXPECT(grown != NULL);
100 EXPECT(grown[0] == 1); // old data copied
101 EXPECT(grown[3] == 4);
102 EXPECT(grown[4] == 0); // new bytes zeroed
103 EXPECT(grown[7] == 0);
104
105 arena_release(&a);
106}
function void * allocator_realloc(Allocator *a, void *ptr, usize old_size, usize new_size)
Resizes a previously allocated block through the allocator.
function void * allocator_alloc(Allocator *a, usize size)
Allocates size zero-initialized bytes through the allocator.
function void allocator_free(Allocator *a, void *ptr, usize size)
Frees a previously allocated block through the allocator.
function Allocator arena_allocator(Arena *arena)
Constructs an Allocator interface backed by an existing Arena.
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 PUSH_ARRAY(arena, type, count)
Allocates and zero-initializes an array of count elements on the arena.
Definition mem_arena.h:252
#define ARENA_COMMIT_SIZE
The granularity at which physical RAM is committed from the OS (64 KB).
Definition mem_arena.h:75
#define PUSH_STRUCT(arena, type)
Allocates and zero-initializes a single struct on the arena.
Definition mem_arena.h:237
#define PUSH_ARRAY_ALIGNED(arena, type, count, alignment)
Allocates a zero-initialized array with an explicit power-of-2 alignment.
Definition mem_arena.h:269
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
ArenaTemp arena_temp_begin(Arena *arena)
Saves the current arena position as a rewind checkpoint.
Definition mem_arena.c:123
uint8_t u8
Definition base_types.h:22
#define MB(x)
Definition base_types.h:84
#define GB(x)
Definition base_types.h:85
size_t usize
Definition base_types.h:43
Generic allocator interface (vtable) for polymorphic memory allocation.
High-performance Virtual Memory Linear (Arena) Allocator.
A generic allocator backed by function pointers (vtable).
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
#define EXPECT(cond)
Evaluates a condition. If it fails, prints the file/line and increments the fail count.
#define TEST_CASE(name)
Defines a test case function.