102 lines
2.1 KiB
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);
|
|
}
|
|
|