OS :: #import "OS$OS.core" Base :: #import "Base.core" ArenaDI: U64 ADDITIONAL_COMMIT_SIZE :: 1024*1024 DEFAULT_RESERVE_SIZE :: 1024*1024*1024 DEFAULT_ALIGNMENT :: 8 Arena :: struct di: U64 // @debug_id memory: OS.Memory alignment: U64 len: U64 Init :: (a: *Arena) a.memory = OS.Reserve(DEFAULT_RESERVE_SIZE) a.alignment = DEFAULT_ALIGNMENT a.di = ArenaDI++ FromBuffer :: (buffer: []U8): Arena a: Arena a.memory.reserve = Len(buffer)->U64 a.memory.commit = Len(buffer)->U64 a.alignment = DEFAULT_ALIGNMENT a.di = ArenaDI++ return a PushSize :: (a: *Arena, size: Base.SizeU): *void generous_size := size + a.alignment if a.len + generous_size > a.memory.commit if a.memory.reserve == 0 Init(a) result := OS.Commit(&a.memory, generous_size + ADDITIONAL_COMMIT_SIZE) Assert(result == true) a.len = Base.AlignUp(a.len, a.alignment) Assert(a.memory.reserve > a.len + a.memory.commit) result: *void = a.memory.data + a.len a.len += size return result Release :: (a: *Arena) OS.Release(&a.memory) PushArray :: (a: *Arena, count: int, $T: Type): *T result := PushSize(a, SizeOf(T) * count->U64) return result->*T PushStruct :: (a: *Arena, $T: Type): *T result := PushSize(a, SizeOf(T)) return result->*T