Files
corelang/memory.c
2022-05-02 09:29:21 +02:00

92 lines
2.0 KiB
C

global const SizeU default_reserve_size = gib(4);
global const SizeU default_alignment = 8;
global const SizeU additional_commit_size = mib(1);
function void
memory_copy(U8 *dst, U8 *src, SizeU size){
for(SizeU i = 0; i < size; i++){
dst[i] = src[i];
}
}
function void
memory_zero(void *p, SizeU size){
U8 *pp = p;
for(SizeU i = 0; i < size; i++)
pp[i] = 0;
}
function void
arena_init(Arena *a){
a->memory = os_reserve(default_reserve_size);
a->alignment = default_alignment;
}
function void *
arena_push_size(Arena *a, SizeU size){
SizeU generous_size = size;
if(a->memory.commit+generous_size>a->memory.commit){
if(a->memory.reserve == 0){
arena_init(a);
}
os_commit(&a->memory, generous_size+additional_commit_size);
}
a->len = align_up(a->len, a->alignment);
void *result = (U8*)a->memory.data + a->len;
a->len += size;
memory_zero(result, size);
return result;
}
function void
arena_pop_pos(Arena *arena, SizeU pos){
pos = clamp_top_sizeu(pos, arena->len);
arena->len = pos;
}
function Arena_Checkpoint
arena_checkpoint(Arena *arena){
Arena_Checkpoint result = {arena, arena->len};
return result;
}
function void
arena_restore(Arena_Checkpoint checkpoint){
arena_pop_pos(checkpoint.arena, checkpoint.pos);
}
function String
arena_push_string_copy(Arena *arena, String string){
U8 *copy = arena_push_array(arena, U8, string.len+1);
memory_copy(copy, string.str, string.len);
copy[string.len] = 0;
return (String){copy, string.len};
}
function String
string_fmtv(Arena *arena, const char *str, va_list args1) {
va_list args2;
va_copy(args2, args1);
U64 len = vsnprintf(0, 0, str, args2);
va_end(args2);
char *result = (char *)arena_push_size(arena, len + 1);
vsnprintf(result, len + 1, str, args1);
if (arena->len > 0)
arena->len -= 1;
return (String){(U8 *)result, len};
}
function String
string_fmt(Arena *arena, const char *str, ...) {
va_list args1;
va_start(args1, str);
String result = string_fmtv(arena, str, args1);
va_end(args1);
return result;
}