35#define FUNCTION_DEFINITIONS
36#define TYPE_DEFINITIONS
37#error "Must define NAME."
39#define ARENA_NAME NAME
46#ifndef FUNCTION_LINKAGE
47#define FUNCTION_LINKAGE
55#define PASTE(a, b) a##b
63#define XPASTE(a, b) PASTE(a, b)
71#define JOIN(a, b) XPASTE(a, XPASTE(_, b))
82#define IS_POW2(X) ((X) != 0 && ((X) & ((X) - 1)) == 0)
86#define ARENA_STATE JOIN(ARENA_NAME, state)
87#define ARENA_TYPE struct ARENA_NAME
88#define ARENA_STATE_TYPE struct ARENA_STATE
99#ifdef TYPE_DEFINITIONS
114struct JOIN(ARENA_NAME, state) {
147FUNCTION_LINKAGE void JOIN(ARENA_NAME, init)(ARENA_TYPE *self,
const size_t len,
unsigned char *backing_buf);
166FUNCTION_LINKAGE void *
JOIN(ARENA_NAME, allocate_aligned)(ARENA_TYPE *self,
const size_t alignment,
const size_t size);
193FUNCTION_LINKAGE void *
JOIN(ARENA_NAME, reallocate_aligned)(ARENA_TYPE *self,
void *old_ptr_,
const size_t alignment,
194 const size_t old_size,
const size_t new_size);
208FUNCTION_LINKAGE void *
JOIN(ARENA_NAME, reallocate)(ARENA_TYPE *self,
void *old_ptr,
const size_t old_size,
209 const size_t new_size);
219#ifdef FUNCTION_DEFINITIONS
225 ARENA_STATE_TYPE curr_state;
226 curr_state.arena_ptr = arena_ptr;
227 curr_state.prev_offset = arena_ptr->prev_offset;
228 curr_state.curr_offset = arena_ptr->curr_offset;
234 prev_state.arena_ptr->prev_offset = prev_state.prev_offset;
235 prev_state.arena_ptr->curr_offset = prev_state.curr_offset;
243 const uintptr_t padding = calc_alignment_padding(
alignof(max_align_t), (uintptr_t)backing_buf);
245 assert(len >= padding);
247 self->buf_ptr = &backing_buf[padding];
248 self->buf_len = len - padding;
249 self->curr_offset = 0;
250 self->prev_offset = 0;
257 self->curr_offset = 0;
258 self->prev_offset = 0;
261FUNCTION_LINKAGE void *
JOIN(ARENA_NAME, allocate_aligned)(ARENA_TYPE *self,
const size_t alignment,
const size_t size)
265 void *ptr = (
void *)&self->buf_ptr[self->curr_offset];
267 size_t space_left = self->buf_len - (size_t)self->curr_offset;
269 const void* has_space_left = align(alignment, size, &ptr, &space_left);
270 if (!has_space_left) {
274 const uintptr_t relative_offset = (uintptr_t)((
unsigned char *)ptr - &self->buf_ptr[0]);
276 self->prev_offset = relative_offset;
277 self->curr_offset = relative_offset + size;
279 memset(ptr, 0, size);
288 return JOIN(ARENA_NAME, allocate_aligned)(self,
alignof(max_align_t), size);
292static inline bool JOIN(
JOIN(internal, ARENA_NAME),
293 try_optimizing_w_prev_offset)(ARENA_TYPE *self,
unsigned char *old_ptr,
const size_t old_size,
294 const size_t new_size)
296 if (&self->buf_ptr[self->prev_offset] != old_ptr) {
300 self->curr_offset = self->prev_offset + new_size;
302 if (new_size > old_size) {
303 const size_t diff = new_size - old_size;
305 memset(&self->buf_ptr[self->curr_offset], 0, diff);
312FUNCTION_LINKAGE void *
JOIN(ARENA_NAME, reallocate_aligned)(ARENA_TYPE *self,
void *old_ptr_,
const size_t alignment,
313 const size_t old_size,
const size_t new_size)
318 unsigned char *old_ptr = (
unsigned char *)old_ptr_;
320 const bool misc_input = old_ptr == NULL || old_size == 0 || new_size == 0;
321 const bool inside_arena_buf = &self->buf_ptr[0] <= old_ptr && old_ptr <= &self->buf_ptr[self->buf_len - 1];
322 if (misc_input || !inside_arena_buf) {
326 const bool has_optimized_w_prev_buf =
327 JOIN(
JOIN(internal, ARENA_NAME), try_optimizing_w_prev_offset)(self, old_ptr, old_size, new_size);
328 if (has_optimized_w_prev_buf) {
332 const size_t copy_size = old_size < new_size ? old_size : new_size;
334 void *new_mem =
JOIN(ARENA_NAME, allocate_aligned)(self, alignment, new_size);
336 memmove(new_mem, old_ptr, copy_size);
342 const size_t new_size)
346 return JOIN(ARENA_NAME, reallocate_aligned)(self, old_ptr,
alignof(max_align_t), old_size, new_size);
355#undef FUNCTION_LINKAGE
356#undef FUNCTION_DEFINITIONS
357#undef TYPE_DEFINITIONS
#define JOIN(a, b)
First expand tokens, then paste them together with a _ in between.
Definition arena_template.h:71
#define IS_POW2(X)
Macro to check if a number is a power of two.
Definition arena_template.h:82
#define FUNCTION_LINKAGE
Specify function linkage e.g. static inline.
Definition fstack_template.h:146
size_t curr_offset
Arena curr offset.
Definition arena_template.h:117
size_t prev_offset
Arena prev offset.
Definition arena_template.h:116
arena_type * arena_ptr
Arena pointer.
Definition arena_template.h:115
unsigned char * buf_ptr
Underlying buffer pointer.
Definition arena_template.h:108
size_t prev_offset
Previous offset relative to buf_ptr.
Definition arena_template.h:106
size_t buf_len
Underlying buffer length.
Definition arena_template.h:105
size_t curr_offset
Current offset relative to buf_ptr.
Definition arena_template.h:107