153 lines
3.8 KiB
C++
153 lines
3.8 KiB
C++
|
//- sixten: Common memory functions
|
||
|
|
||
|
static void Copy(void *Dest, void *Source, umm Count)
|
||
|
{
|
||
|
u8 *Dest8 = (u8 *)Dest;
|
||
|
u8 *Source8 = (u8 *)Source;
|
||
|
|
||
|
while(Count--)
|
||
|
{
|
||
|
*Dest8++ = *Source8++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void Fill(void *Dest, u8 Value, umm Count)
|
||
|
{
|
||
|
u8 *Dest8 = (u8 *)Dest;
|
||
|
|
||
|
while(Count--)
|
||
|
{
|
||
|
*Dest8++ = Value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//- sixten: Memory arena functions
|
||
|
|
||
|
static void Release(memory_arena *Arena)
|
||
|
{
|
||
|
while(Arena->CurrentBlock != 0)
|
||
|
{
|
||
|
platform_memory_block *MemoryBlock = Arena->CurrentBlock;
|
||
|
b32 IsLastBlock = (MemoryBlock->ArenaPrev == 0);
|
||
|
Arena->CurrentBlock = MemoryBlock->ArenaPrev;
|
||
|
Platform.DeallocateMemory(MemoryBlock);
|
||
|
|
||
|
if(IsLastBlock)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline umm GetAlignmentOffset(memory_arena *Arena, umm Alignment)
|
||
|
{
|
||
|
umm AlignmentOffset = 0;
|
||
|
|
||
|
umm ResultPointer = (umm)Arena->CurrentBlock + Arena->CurrentBlock->Used;
|
||
|
umm AlignmentMask = Alignment - 1;
|
||
|
if(ResultPointer & AlignmentMask)
|
||
|
{
|
||
|
AlignmentOffset = Alignment - (ResultPointer & AlignmentMask);
|
||
|
}
|
||
|
|
||
|
return(AlignmentOffset);
|
||
|
}
|
||
|
|
||
|
inline umm GetEffectiveSizeFor(memory_arena *Arena, umm InitialSize, arena_push_params Params)
|
||
|
{
|
||
|
umm Size = InitialSize;
|
||
|
|
||
|
umm AlignmentOffset = GetAlignmentOffset(Arena, Params.Alignment);
|
||
|
Size += AlignmentOffset;
|
||
|
|
||
|
return(Size);
|
||
|
}
|
||
|
|
||
|
static void *PushSize_(memory_arena *Arena, umm InitialSize, arena_push_params Params)
|
||
|
{
|
||
|
void *Result = 0;
|
||
|
|
||
|
umm Size = 0;
|
||
|
if(Arena->CurrentBlock)
|
||
|
{
|
||
|
Size = GetEffectiveSizeFor(Arena, InitialSize, Params);
|
||
|
}
|
||
|
|
||
|
if(!Arena->CurrentBlock || ((Arena->CurrentBlock->Used + Size) > Arena->CurrentBlock->Size))
|
||
|
{
|
||
|
Size = InitialSize;
|
||
|
|
||
|
if(!Arena->MinimumBlockSize)
|
||
|
{
|
||
|
Arena->MinimumBlockSize = 1024*1024;
|
||
|
}
|
||
|
|
||
|
umm BlockSize = Maximum(Size, Arena->MinimumBlockSize);
|
||
|
|
||
|
platform_memory_block *NewBlock = Platform.AllocateMemory(BlockSize);
|
||
|
NewBlock->ArenaPrev = Arena->CurrentBlock;
|
||
|
Arena->CurrentBlock = NewBlock;
|
||
|
}
|
||
|
|
||
|
Assert((Arena->CurrentBlock->Used + Size) <= Arena->CurrentBlock->Size);
|
||
|
|
||
|
umm AlignmentOffset = GetAlignmentOffset(Arena, Params.Alignment);
|
||
|
umm OffsetInBlock = Arena->CurrentBlock->Used + AlignmentOffset;
|
||
|
Result = Arena->CurrentBlock->Base + OffsetInBlock;
|
||
|
Arena->CurrentBlock->Used += Size;
|
||
|
|
||
|
Assert(Size >= InitialSize);
|
||
|
Assert(Arena->CurrentBlock->Used <= Arena->CurrentBlock->Size);
|
||
|
|
||
|
if(Params.Flags & ArenaFlag_ClearToZero)
|
||
|
{
|
||
|
Fill(Result, 0, InitialSize);
|
||
|
}
|
||
|
|
||
|
return(Result);
|
||
|
}
|
||
|
|
||
|
//- sixten: Bootsrapping helpers
|
||
|
|
||
|
static void *BootstrapPushSize(umm Size, umm OffsetToArena)
|
||
|
{
|
||
|
memory_arena Arena = {};
|
||
|
void *Result = PushSize(&Arena, Size);
|
||
|
*(memory_arena *)((u8 *)Result + OffsetToArena) = Arena;
|
||
|
|
||
|
return(Result);
|
||
|
}
|
||
|
|
||
|
//- sixten: Temporary memory functions
|
||
|
|
||
|
static temporary_memory BeginTemporaryMemory(memory_arena *Arena)
|
||
|
{
|
||
|
temporary_memory Result;
|
||
|
Result.Arena = Arena;
|
||
|
Result.Block = Arena->CurrentBlock;
|
||
|
Result.Used = Arena->CurrentBlock ? Arena->CurrentBlock->Used : 0;
|
||
|
|
||
|
++Arena->TemporaryMemoryCount;
|
||
|
|
||
|
return(Result);
|
||
|
}
|
||
|
|
||
|
static void EndTemporaryMemory(temporary_memory Temp)
|
||
|
{
|
||
|
memory_arena *Arena = Temp.Arena;
|
||
|
while(Arena->CurrentBlock != Temp.Block)
|
||
|
{
|
||
|
platform_memory_block *MemoryBlock = Arena->CurrentBlock;
|
||
|
Arena->CurrentBlock = MemoryBlock->ArenaPrev;
|
||
|
Platform.DeallocateMemory(MemoryBlock);
|
||
|
}
|
||
|
|
||
|
if(Arena->CurrentBlock)
|
||
|
{
|
||
|
Assert(Arena->CurrentBlock->Used >= Temp.Used);
|
||
|
Arena->CurrentBlock->Used = Temp.Used;
|
||
|
}
|
||
|
|
||
|
Assert(Arena->TemporaryMemoryCount > 0);
|
||
|
--Arena->TemporaryMemoryCount;
|
||
|
}
|