power_play/src/base/base_arena.h

79 lines
2.7 KiB
C

////////////////////////////////////////////////////////////
//~ Arena types
#define ArenaHeaderSize 256
#define ArenaBlockSize 16384
Struct(ThreadLocalArenaCtx)
{
Arena *perm;
Arena *scratch[2];
};
////////////////////////////////////////////////////////////
//~ Arena management
Arena *AcquireArena(u64 reserve);
void ReleaseArena(Arena *arena);
void CopyArena(Arena *dst, Arena *src);
void ShrinkArena(Arena *arena);
void SetArenaReadonly(Arena *arena);
void SetArenaReadWrite(Arena *arena);
void *ResetArena(Arena *arena);
////////////////////////////////////////////////////////////
//~ Push / pop
#define PushStructs(a, type, n) ((type *)PushBytes((a), (sizeof(type) * (n)), alignof(type)))
#define PushStruct(a, type) PushStructs((a), type, 1)
#define PushStructsNoZero(a, type, n) ((type *)PushBytesNoZero((a), (sizeof(type) * (n)), alignof(type)))
#define PushStructNoZero(a, type) PushStructsNoZero((a), type, 1)
#define PopStructs(a, type, dst, n) PopBytes((a), sizeof(type) * (n), dst)
#define PopStruct(a, type, dst) PopStructs((a), type, (dst), 1)
#define PopStructsNoCopy(a, type, n) PopBytesNoCopy((a), sizeof(type) * (n))
#define PopStructNoCopy(a, type) PopStructsNoCopy((a), type, 1)
#define ArenaFirst(arena, type) ((type *)ArenaFirst_((arena), alignof(type)))
#define ArenaNext(arena, type) ((type *)ArenaNext_((arena), alignof(type)))
#define ArenaCount(arena, type) ((arena)->pos / sizeof(type))
void *PushBytesNoZero(Arena *arena, u64 size, u64 align);
void *PushBytes(Arena *arena, u64 size, u64 align);
void *PushAlign(Arena *arena, u64 align);
void PopTo(Arena *arena, u64 pos);
void PopBytesNoCopy(Arena *arena, u64 size);
void PopBytes(Arena *arena, u64 size, void *copy_dst);
void *ArenaNext_(Arena *arena, u64 align);
void *ArenaFirst_(Arena *arena, u64 align);
////////////////////////////////////////////////////////////
//~ Thread arena helpers
TempArena BeginTempArena(Arena *arena);
void EndTempArena(TempArena temp);
#define PermArena() (Base_tl.arenas.perm)
////////////////////////////////////////////////////////////
//~ Scratch arena helpers
TempArena BeginScratch(Arena *potential_conflict);
TempArena BeginScratchNoConflict_(void);
void EndScratch(TempArena scratch_temp);
// This macro declares an unused "arena" variable that will produce a shadowing
// warning variable is present (due to shadowing). This is for catching obvious
// cases of `BeginScratchNoConflict` getting called when an `arena` variable
// already exists in the caller's scope.
#define BeginScratchNoConflict() \
BeginScratchNoConflict_(); \
do { \
u8 arena = 0; \
} while (0)