infix
A JIT-Powered FFI Library for C
Loading...
Searching...
No Matches
arena.c
Go to the documentation of this file.
1
37#include <stdint.h>
38#include <stdlib.h>
39#include <string.h>
53 // Use calloc to ensure the initial struct state is zeroed.
55 if (arena == nullptr) {
57 return nullptr;
58 }
59 arena->buffer = infix_calloc(1, initial_size);
60 if (arena->buffer == nullptr && initial_size > 0) {
63 return nullptr;
64 }
65 arena->capacity = initial_size;
67 arena->error = false;
68 arena->next_block = nullptr;
69 arena->block_size = initial_size;
70 return arena;
71}
84 if (arena == nullptr)
85 return;
86 // Traverse the chain of blocks and free each one.
87 infix_arena_t * current = arena;
88 while (current != nullptr) {
89 infix_arena_t * next = current->next_block;
90 if (current->buffer)
91 infix_free(current->buffer);
92 infix_free(current);
93 current = next;
94 }
95}
117INFIX_API c23_nodiscard void * infix_arena_alloc(infix_arena_t * arena, size_t size, size_t alignment) {
118 if (arena == nullptr)
119 return nullptr;
120
121 // Ensure alignment is power of 2
122 if (alignment == 0 || (alignment & (alignment - 1)) != 0) {
123 arena->error = true;
125 return nullptr;
126 }
127
128 infix_arena_t * block = arena;
129 while (true) {
130 if (block->error)
131 return nullptr;
132
133 // 1. Calculate current absolute address
134 uintptr_t current_ptr = (uintptr_t)(block->buffer + block->current_offset);
135
136 // 2. Calculate aligned address
137 // (x + align - 1) & ~(align - 1)
138 uintptr_t aligned_ptr = (current_ptr + (alignment - 1)) & ~(alignment - 1);
139
140 // 3. Calculate padding needed
141 size_t padding = (size_t)(aligned_ptr - current_ptr);
142
143 // 4. Calculate total space required in this block
144 size_t total_needed = size + padding;
145
146 // Check if fits in current block
147 if (block->current_offset + total_needed <= block->capacity) {
148 void * ret = (void *)aligned_ptr;
149 block->current_offset += total_needed;
150 return ret;
151 }
152
153 // 5. Allocation failed in current block. Check next or create new.
154 if (block->next_block) {
155 block = block->next_block;
156 continue;
157 }
158
159 // Create new block. Ensure it's large enough for alignment + size.
160 size_t next_cap = block->block_size * 2;
161 if (next_cap < size + alignment)
162 next_cap = size + alignment;
163
164 block->next_block = infix_arena_create(next_cap);
165 if (!block->next_block) {
166 block->error = true;
167 return nullptr;
168 }
169
170 block = block->next_block;
171 }
172}
188INFIX_API c23_nodiscard void * infix_arena_calloc(infix_arena_t * arena, size_t num, size_t size, size_t alignment) {
189 // Security: Check for multiplication overflow.
190 if (size > 0 && num > SIZE_MAX / size) {
191 if (arena)
192 arena->error = true;
194 return nullptr;
195 }
196 size_t total_size = num * size;
197 void * ptr = infix_arena_alloc(arena, total_size, alignment);
198 if (ptr != nullptr)
199 memset(ptr, 0, total_size);
200 return ptr;
201}
infix_arena_t * arena
Definition 005_layouts.c:62
#define c23_nodiscard
Internal alias for the public INFIX_NODISCARD macro.
Definition compat_c23.h:91
@ INFIX_CODE_INVALID_ALIGNMENT
Definition infix.h:1353
@ INFIX_CODE_INTEGER_OVERFLOW
Definition infix.h:1360
@ INFIX_CODE_OUT_OF_MEMORY
Definition infix.h:1350
@ INFIX_CATEGORY_ALLOCATION
Definition infix.h:1335
@ INFIX_CATEGORY_GENERAL
Definition infix.h:1334
#define infix_free
A macro that can be defined to override the default free function.
Definition infix.h:382
INFIX_API c23_nodiscard void * infix_arena_alloc(infix_arena_t *arena, size_t size, size_t alignment)
Allocates a block of memory from an arena.
Definition arena.c:117
#define infix_calloc
A macro that can be defined to override the default calloc function.
Definition infix.h:374
INFIX_API c23_nodiscard infix_arena_t * infix_arena_create(size_t initial_size)
Creates a new memory arena.
Definition arena.c:52
INFIX_API c23_nodiscard void * infix_arena_calloc(infix_arena_t *arena, size_t num, size_t size, size_t alignment)
Allocates and zero-initializes a block of memory from an arena.
Definition arena.c:188
INFIX_API void infix_arena_destroy(infix_arena_t *arena)
Destroys an arena and frees all memory allocated from it.
Definition arena.c:83
#define INFIX_API
Symbol visibility macro.
Definition infix.h:114
Internal data structures, function prototypes, and constants.
INFIX_INTERNAL void _infix_set_error(infix_error_category_t category, infix_error_code_t code, size_t position)
Sets the thread-local error state with detailed information.
Definition error.c:173
Internal definition of a memory arena.
Definition infix_internals.h:138
char * buffer
Definition infix_internals.h:139
bool error
Definition infix_internals.h:142
size_t capacity
Definition infix_internals.h:140
size_t block_size
Definition infix_internals.h:144
size_t current_offset
Definition infix_internals.h:141
struct infix_arena_t * next_block
Definition infix_internals.h:143