Reorganize files to base/ folder (#1)
This commit was merged in pull request #1.
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
#pragma once
|
||||
#include "core.h"
|
||||
|
||||
// Mini Arena for arena allocations from a supplied buffer
|
||||
|
||||
typedef struct MArena MArena;
|
||||
struct MArena {
|
||||
U8 *base; // start of buffer
|
||||
U32 first_free;
|
||||
U32 size;
|
||||
S32 temp_level; // level of marena_temp_begin nesting
|
||||
};
|
||||
|
||||
typedef struct MTemp MTemp;
|
||||
struct MTemp {
|
||||
U32 offset;
|
||||
MArena *arena;
|
||||
};
|
||||
|
||||
#define MARENA_STATIC_INITIALIZER(data) MARENA_INITIALIZER((data), sizeof(data))
|
||||
#define MARENA_INITIALIZER(data, size_) {.base = (data), .first_free = 0, .size = (U32)size_, .temp_level = 0}
|
||||
#define MARENA_DEFINE(var_name, size, alignment_) \
|
||||
struct { \
|
||||
_Alignas(alignment_) U8 memory[size];\
|
||||
} var_name##_marena_memory; \
|
||||
MArena var_name = MARENA_STATIC_INITIALIZER(var_name##_marena_memory.memory)
|
||||
|
||||
|
||||
|
||||
static INLINE void marena_init(MArena *arena, void *memory, U32 size)
|
||||
{
|
||||
Assert(memory != NULL);
|
||||
arena->base = (U8 *)memory;
|
||||
arena->first_free = 0;
|
||||
arena->size = size;
|
||||
}
|
||||
|
||||
static INLINE MTemp marena_temp_begin(MArena *arena)
|
||||
{
|
||||
MTemp checkpoint = {};
|
||||
|
||||
checkpoint.arena = arena;
|
||||
checkpoint.offset = arena->first_free;
|
||||
arena->temp_level++;
|
||||
|
||||
return checkpoint;
|
||||
}
|
||||
|
||||
static INLINE void marena_temp_end(MTemp *state)
|
||||
{
|
||||
MArena *arena = state->arena;
|
||||
Assert(arena->temp_level > 0);
|
||||
arena->first_free = state->offset;
|
||||
arena->temp_level--;
|
||||
}
|
||||
|
||||
static INLINE void *marena_push(MArena *arena, U32 size)
|
||||
{
|
||||
if (size > arena->size - arena->first_free) {
|
||||
return NULL;
|
||||
}
|
||||
void *base = &arena->base[arena->first_free];
|
||||
arena->first_free += size;
|
||||
return base;
|
||||
}
|
||||
|
||||
[[gnu::alloc_align(3)]]
|
||||
static INLINE void *marena_push_aligned(MArena *arena, U32 size, U32 align)
|
||||
{
|
||||
Assert(IsPow2(align));
|
||||
|
||||
U32 aligned = AlignUp(arena->first_free, align);
|
||||
if (aligned < arena->first_free) { // aligned wrapped around
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (aligned > arena->size || size > arena->size - aligned) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *base = &arena->base[aligned];
|
||||
arena->first_free = aligned + size;
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
#define marena_push_type(arena, type_)\
|
||||
marena_push_aligned((arena), sizeof(type_), _Alignof(type_))
|
||||
#define marena_push_array(arena, type_, nr_elements_)\
|
||||
marena_push_aligned((arena), (nr_elements_) * (U32)sizeof(type_), _Alignof(type_))
|
||||
|
||||
|
||||
static INLINE void marena_reset(MArena *arena)
|
||||
{
|
||||
arena->first_free = 0;
|
||||
}
|
||||
|
||||
static INLINE void *marena_allocator_func(Allocator *allocator, AllocOperation operation , void *memory, U32 size, U32 align)
|
||||
{
|
||||
switch (operation) {
|
||||
case Alloc_Op_Aligned:
|
||||
return marena_push_aligned(allocator->data, size, align);
|
||||
|
||||
case Alloc_Op_Free: // can't free/Free_all from an marena
|
||||
return NULL;
|
||||
|
||||
case Alloc_Op_Free_All:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Assert(false);
|
||||
}
|
||||
|
||||
static INLINE Allocator marena_allocator(MArena *arena)
|
||||
{
|
||||
Allocator allocator = {};
|
||||
allocator.op_func_ptr = marena_allocator_func;
|
||||
allocator.data = arena;
|
||||
|
||||
return allocator;
|
||||
}
|
||||
Reference in New Issue
Block a user