92 lines
2.3 KiB
C
92 lines
2.3 KiB
C
|
|
#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_ArenaOpts) { .count = 1, .align = Alignof(T), ##__VA_ARGS__ })
|
||
|
|
#define M_ArenaPushCopy(arena, T, src, ...) (T *) _M_ArenaPush(arena, src, sizeof(T), &(M_ArenaOpts) { .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_
|