35#define restrict __restrict__
50#ifndef FUNCTION_LINKAGE
51#define FUNCTION_LINKAGE
62#define IS_POW2(X) ((X) != 0 && ((X) & ((X) - 1)) == 0)
76#ifdef TYPE_DEFINITIONS
85 unsigned char *buf_ptr;
92 struct arena *arena_ptr;
178 const size_t old_size,
const size_t new_size);
202#ifdef FUNCTION_DEFINITIONS
215 struct arena_state curr_state;
216 curr_state.arena_ptr = arena_ptr;
217 curr_state.prev_offset = arena_ptr->prev_offset;
218 curr_state.curr_offset = arena_ptr->curr_offset;
224 prev_state.arena_ptr->prev_offset = prev_state.prev_offset;
225 prev_state.arena_ptr->curr_offset = prev_state.curr_offset;
233 struct arena *self = (
struct arena *)self_;
235 const uintptr_t padding = calc_alignment_padding(
alignof(max_align_t), (uintptr_t)backing_buf);
237 assert(len >= padding);
239 self->buf_ptr = &backing_buf[padding];
240 self->buf_len = len - padding;
241 self->curr_offset = 0;
242 self->prev_offset = 0;
249 struct arena *self = (
struct arena *)self_;
251 self->curr_offset = 0;
252 self->prev_offset = 0;
267 struct arena *self = (
struct arena *)self_;
269 void *ptr = (
void *)&self->buf_ptr[self->curr_offset];
271 size_t space_left = self->buf_len - (size_t)self->curr_offset;
273 const bool has_space_left = align(alignment, size, &ptr, &space_left);
274 if (!has_space_left) {
278 const uintptr_t relative_offset = (uintptr_t)((
unsigned char *)ptr - &self->buf_ptr[0]);
280 self->prev_offset = relative_offset;
281 self->curr_offset = relative_offset + size;
283 memset(ptr, 0, size);
296static inline void *internal_arena_try_optimizing_w_prev_offset(
struct arena *self,
unsigned char *old_ptr,
297 const size_t old_size,
const size_t new_size)
299 if (&self->buf_ptr[self->prev_offset] != old_ptr) {
303 self->curr_offset = self->prev_offset + new_size;
305 if (new_size > old_size) {
306 const size_t diff = new_size - old_size;
308 memset(&self->buf_ptr[self->curr_offset], 0, diff);
316 const size_t old_size,
const size_t new_size)
321 struct arena *self = (
struct arena *)self_;
322 unsigned char *old_ptr = (
unsigned char *)old_ptr_;
324 const bool misc_input = old_ptr == NULL || old_size == 0 || new_size == 0;
325 const bool inside_arena_buf = &self->buf_ptr[0] <= old_ptr && old_ptr <= &self->buf_ptr[self->buf_len - 1];
326 if (misc_input || !inside_arena_buf) {
330 const bool has_optimized_w_prev_buf =
331 internal_arena_try_optimizing_w_prev_offset(self, old_ptr, old_size, new_size);
332 if (has_optimized_w_prev_buf) {
336 const size_t copy_size = old_size < new_size ? old_size : new_size;
340 memmove(new_mem, old_ptr, copy_size);
358#undef FUNCTION_LINKAGE
359#undef FUNCTION_DEFINITIONS
360#undef TYPE_DEFINITIONS
void arena_deallocate(void *self_, void *mem)
Dummy no-op deallocate function.
#define IS_POW2(X)
Macro to check if a number is a power of two.
Definition arena_template.h:62
struct arena_state arena_state_save(struct arena *arena_ptr)
Save the arena state temporarily.
void arena_state_restore(struct arena_state prev_state)
Restore the arena state.
void * arena_allocate(void *self_, const size_t size)
Get the pointer to a chunk of the arena.
void * arena_allocate_aligned(void *self_, const size_t alignment, const size_t size)
Get the pointer to a chunk of the arena. With specific alignment.
void arena_init(void *self_, const size_t len, unsigned char *backing_buf)
Initialize the arena.
void * arena_reallocate_aligned(void *self_, void *old_ptr_, const size_t alignment, const size_t old_size, const size_t new_size)
Reallocate a previously allocated chunk in the arena. With specific aligment.
void * arena_reallocate(void *self_, void *old_ptr, const size_t old_size, const size_t new_size)
Reallocate a previously allocated chunk in the arena.
void arena_deallocate_all(void *self_)
Deallocate all allocations in the arena.
#define FUNCTION_LINKAGE
Specify function linkage e.g. static inline.
Definition fstack_template.h:146