101 lines
2.6 KiB
C
101 lines
2.6 KiB
C
#include "all.h"
|
|
|
|
fn u64 alignForward(u64 pointer, u64 align) {
|
|
u64 p, modulo;
|
|
assert(isPowerOfTwo(align));
|
|
p = pointer;
|
|
// Same as (p % a) but faster as 'a' is a power of two
|
|
modulo = p & (align-1);
|
|
if (modulo != 0) {
|
|
// If 'p' address is not aligned, push the address to the
|
|
// next value which is aligned
|
|
p += align - modulo;
|
|
}
|
|
return p;
|
|
}
|
|
|
|
fn void* arenaAlloc(Arena* arena, u64 size) {
|
|
void* memory = 0;
|
|
size = alignForward(size, DEFAULT_ALIGNMENT);
|
|
if (arena->alloc_position + size > arena->commit_position) {
|
|
if (!arena->static_size) {
|
|
u64 commit_size = size;
|
|
|
|
commit_size += ARENA_COMMIT_SIZE - 1;
|
|
commit_size -= commit_size % ARENA_COMMIT_SIZE;
|
|
|
|
if (arena->commit_position < arena->max) {
|
|
osMemoryCommit(arena->memory + arena->commit_position, commit_size);
|
|
arena->commit_position += commit_size;
|
|
} else {
|
|
assert(0 && "Arena is out of memory");
|
|
}
|
|
} else {
|
|
assert(0 && "Static-Size Arena is out of memory");
|
|
}
|
|
}
|
|
|
|
memory = arena->memory + arena->alloc_position;
|
|
arena->alloc_position += size;
|
|
return memory;
|
|
}
|
|
|
|
fn void* arenaAllocZero(Arena* a, u64 size) {
|
|
void* result = arenaAlloc(a, size);
|
|
MemoryZero(result, size);
|
|
return result;
|
|
}
|
|
|
|
fn void* arenaAllocArraySized(Arena* arena, u64 elem_size, u64 count) {
|
|
return arenaAlloc(arena, elem_size * count);
|
|
}
|
|
|
|
fn void arenaDealloc(Arena* arena, u64 size) {
|
|
if (size > arena->alloc_position) size = arena->alloc_position;
|
|
arena->alloc_position -= size;
|
|
}
|
|
|
|
fn void arenaInit(Arena* arena) {
|
|
MemoryZeroStruct(arena, Arena);
|
|
arena->max = ARENA_MAX;
|
|
arena->memory = osMemoryReserve(arena->max);
|
|
arena->alloc_position = 0;
|
|
arena->commit_position = 0;
|
|
arena->static_size = false;
|
|
}
|
|
|
|
// WARNING: segfault problems with this approach
|
|
fn void arenaInitStatic(Arena* arena, u64 max) {
|
|
MemoryZeroStruct(arena, Arena);
|
|
arena->max = max;
|
|
arena->memory = osMemoryReserve(arena->max);
|
|
osMemoryCommit(arena->memory, max + (max % ARENA_COMMIT_SIZE));
|
|
arena->alloc_position = 0;
|
|
arena->commit_position = 0;
|
|
arena->static_size = true;
|
|
}
|
|
|
|
|
|
fn void arenaClear(Arena* a) {
|
|
a->alloc_position = 0;
|
|
}
|
|
|
|
fn void arenaFree(Arena* a) {
|
|
osMemoryRelease(a->memory, a->max);
|
|
}
|
|
|
|
ScratchMem scratchGet(void) {
|
|
ThreadContext* ctx = (ThreadContext*)osThreadContextGet();
|
|
return tctxScratchGet(ctx);
|
|
}
|
|
|
|
void scratchReset(ScratchMem* scratch) {
|
|
ThreadContext* ctx = (ThreadContext*)osThreadContextGet();
|
|
tctxScratchReset(ctx, scratch);
|
|
}
|
|
|
|
void scratchReturn(ScratchMem* scratch) {
|
|
ThreadContext* ctx = (ThreadContext*)osThreadContextGet();
|
|
tctxScratchReturn(ctx, scratch);
|
|
}
|