Files
ld58/code/core/arena.h

92 lines
2.3 KiB
C
Raw Permalink Normal View History

#if !defined(LD_CORE_ARENA_H_)
#define LD_CORE_ARENA_H_
#define AlignUp(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
#define AlignDown(x, a) (((x)) & ~((a) - 1))
#define KB(x) ((U64) (x) << 10)
#define MB(x) ((U64) (x) << 20)
#define GB(x) ((U64) (x) << 30)
#if !defined(M_ARENA_CHAIN_RESERVE)
#define M_ARENA_CHAIN_RESERVE MB(4)
#endif
function void *M_ZeroSize(void *base, U64 size);
function void *M_CopySize(void *dst, void *src, U64 size);
typedef U32 M_ArenaFlags;
enum {
// Arena is fixed size, so will not chain
M_ARENA_FIXED_SIZE = (1 << 0),
// Don't clear allocation
M_ARENA_NO_ZERO = (1 << 1)
};
typedef union M_Arena M_Arena;
union M_Arena {
struct {
M_Arena *current;
M_Arena *prev;
U64 base;
U64 limit;
U64 offset;
U64 committed;
U64 increment;
M_ArenaFlags flags;
};
U8 __pad[64];
};
typedef struct M_ArenaOpts M_ArenaOpts;
struct M_ArenaOpts {
U64 initial;
U64 increment;
M_ArenaFlags flags;
};
typedef struct M_ArenaPushOpts M_ArenaPushOpts;
struct M_ArenaPushOpts {
U64 count;
U64 align;
M_ArenaFlags flags;
};
function M_Arena *_M_ArenaAlloc(U64 limit, M_ArenaOpts *opts);
function void *_M_ArenaPush(M_Arena *arena, U64 esize, M_ArenaPushOpts *opts);
function void *_M_ArenaPushCopy(M_Arena *arena, void *src, U64 esize, M_ArenaPushOpts *opts);
#define M_ArenaAlloc(limit, ...) _M_ArenaAlloc(limit, &(M_ArenaOpts) { .initial = MB(1), .increment = KB(64), ##__VA_ARGS__ })
#define M_ArenaPush(arena, T, ...) (T *) _M_ArenaPush(arena, sizeof(T), &(M_ArenaPushOpts) { .count = 1, .align = Alignof(T), ##__VA_ARGS__ })
#define M_ArenaPushCopy(arena, T, src, ...) (T *) _M_ArenaPush(arena, src, sizeof(T), &(M_ArenaPushOpts) { .count = 1, .align = Alignof(T), ##__VA_ARGS__ })
function void M_ArenaReset(M_Arena *arena);
function void M_ArenaRelease(M_Arena *arena);
function U64 M_ArenaOffset(M_Arena *arena);
function void M_ArenaPop(M_Arena *arena, U64 offset);
function void M_ArenaPopSize(M_Arena *arena, U64 size);
// Temporary memory
typedef struct M_Temp M_Temp;
struct M_Temp {
M_Arena *arena;
U64 offset;
};
function M_Temp M_TempAcquire(U64 count, M_Arena **conflicts);
function void M_TempRelease(M_Temp temp);
#define M_TempScope(n, c) for (M_Temp temp = M_TempAcquire(n, c); temp.arena != 0; M_TempRelease(temp), temp.arena = 0)
#endif // LD_CORE_ARENA_H_