splink/source/app_memory.c

102 lines
2.1 KiB
C

// NOTE(allen): memory
#define M_ARENA_MAX Gigabytes(4)
#define M_ARENA_COMMIT_SIZE Kilobytes(4)
internal M_Arena
M_ArenaInitializeWithAlign(u64 auto_align)
{
M_Arena arena = {0};
arena.max = M_ARENA_MAX;
arena.base = os->Reserve(arena.max);
arena.alloc_position = 0;
arena.commit_position = 0;
arena.auto_align = auto_align;
return arena;
}
internal M_Arena
M_ArenaInitialize(void)
{
return(M_ArenaInitializeWithAlign(8));
}
internal void *
M_ArenaPush(M_Arena *arena, u64 size)
{
void *memory = 0;
if(arena->alloc_position + size > arena->commit_position)
{
u64 commit_size = size;
commit_size += M_ARENA_COMMIT_SIZE-1;
commit_size -= commit_size % M_ARENA_COMMIT_SIZE;
os->Commit((u8 *)arena->base + arena->commit_position, commit_size);
arena->commit_position += commit_size;
}
memory = (u8 *)arena->base + arena->alloc_position;
u64 p = arena->alloc_position + size;
arena->alloc_position = (p + arena->auto_align - 1)&(~(arena->auto_align - 1));
return memory;
}
internal void *
M_ArenaPushZero(M_Arena *arena, u64 size)
{
void *memory = M_ArenaPush(arena, size);
MemorySet(memory, 0, size);
return memory;
}
internal void
M_ArenaSetPosBack(M_Arena *arena, u64 pos)
{
if (pos <= arena->alloc_position)
{
arena->alloc_position = pos;
}
}
internal void
M_ArenaSetPosBackByPtr(M_Arena *arena, void *ptr)
{
u8 *uptr = (u8*)ptr;
u64 pos = (uptr - (u8*)arena->base);
if ((u8*)arena->base <= uptr)
{
M_ArenaSetPosBack(arena, pos);
}
}
internal void
M_ArenaPop(M_Arena *arena, u64 size)
{
size = ClampTop(size, arena->alloc_position);
arena->alloc_position -= size;
}
internal void
M_ArenaClear(M_Arena *arena)
{
M_ArenaPop(arena, arena->alloc_position);
}
internal void
M_ArenaRelease(M_Arena *arena)
{
os->Release(arena->base);
}
internal M_Temp
M_BeginTemp(M_Arena *arena)
{
M_Temp temp = {arena, arena->alloc_position};
return(temp);
}
internal void
M_EndTemp(M_Temp temp)
{
M_ArenaSetPosBack(temp.arena, temp.pos);
}