Introduce the allocator stuff again

This commit is contained in:
Krzosa Karol
2022-12-31 16:51:01 +01:00
parent e20edaa3a2
commit 55515ff420
12 changed files with 71 additions and 44 deletions

View File

@@ -139,7 +139,6 @@ typedef double F64;
#define JOIN(X,Y) JOIN1(X,Y)
#define string_expand(x) (int)x.len, x.str
#define CORE_STRINGS
struct String{
U8 *str;
S64 len;
@@ -150,6 +149,14 @@ union Intern_String{ // Basically just String
struct{ U8 *str; S64 len; };
};
struct Allocator {
typedef void *Allocate(Allocator *, size_t);
typedef void Deallocate(Allocator *, void *p);
Allocate *allocate;
Deallocate *deallocate;
};
global String string_null = {(U8 *)"null", 4};
#include <stdio.h>
#define STB_SPRINTF_IMPLEMENTATION
@@ -405,10 +412,20 @@ operator!=(Intern_String a, Intern_String b){
#define Iter_Named(list, it) for(auto it = iterate(list); should_we_continue(&it); advance(&it))
#define Iter(list) Iter_Named(list, it)
enum Alloc_Flag{
AF_None,
AF_ZeroMemory
};
#define allocate_array(a, T, size,...) (T *)allocate_size(a, sizeof(T)*(size),##__VA_ARGS__)
#define allocate_struct(a, T, ...) allocate_array(a, T, 1,##__VA_ARGS__)
CORE_Static void *allocate_size(Allocator *allocator, size_t size, bool zero_memory = true) {
void *result = allocator->allocate(allocator, size);
if (zero_memory) {
memory_zero(result, size);
}
return result;
}
CORE_Static void deallocate(Allocator *allocator, void *p) {
assert(p);
allocator->deallocate(allocator, p);
}
//-----------------------------------------------------------------------------
// Memory OS
@@ -428,13 +445,12 @@ CORE_Static B32 os_decommit_pos(OS_Memory *m, size_t pos);
global const size_t default_reserve_size = gib(4);
global const size_t default_alignment = 8;
global const size_t additional_commit_size = mib(1);
struct Arena{
struct Arena : Allocator {
OS_Memory memory;
size_t alignment;
size_t len;
String debug_string;
};
CORE_Static void arena_init(Arena *arena, String debug_name);
CORE_Static void
arena_pop_pos(Arena *arena, size_t pos){
@@ -459,15 +475,15 @@ arena_clear(Arena *arena){
arena_pop_pos(arena, 0);
}
#define arena_push_array(a, T, size,...) (T *)arena_push_size(a, sizeof(T)*(size),##__VA_ARGS__)
#define arena_push_type(a, T, ...) arena_push_array(a, T, 1,##__VA_ARGS__)
CORE_Static void
deallocate_stub(Allocator *, void *) {
}
CORE_Static void *
arena_push_size(Arena *a, size_t size, Alloc_Flag flags = AF_None){
arena_push_size(Arena *a, size_t size){
size_t generous_size = size + a->alignment;
if(a->len+generous_size>a->memory.commit){
if(a->memory.reserve == 0){
arena_init(a, "Zero initialized arena"_s);
}
assert(a->memory.reserve > 0);
B32 result = os_commit(&a->memory, generous_size+additional_commit_size);
assert(result);
}
@@ -477,18 +493,16 @@ arena_push_size(Arena *a, size_t size, Alloc_Flag flags = AF_None){
void *result = (U8*)a->memory.data + a->len;
a->len += size;
if(flags & AF_ZeroMemory){
memory_zero(result, size);
}
return result;
}
CORE_Static void
arena_init(Arena *a, String debug_name){
a->memory = os_reserve(default_reserve_size);
a->alignment = default_alignment;
a->memory = os_reserve(default_reserve_size);
a->alignment = default_alignment;
a->debug_string = debug_name;
a->allocate = (Allocator::Allocate *)arena_push_size;
a->deallocate = (Allocator::Deallocate *)deallocate_stub;
}
enum Log_Kind{Log_Kind_Normal_No_NewLine, Log_Kind_Normal, Log_Kind_Error, Log_Kind_Trace};
@@ -536,6 +550,7 @@ struct Scratch{
arena_pop_pos(arena, saved_pos);
}
force_inline operator Arena*(){ return arena; }
force_inline operator Allocator*(){ return arena; }
// @Note: Disable copy constructors, cause it caused lots of confusing errors
// Where it passed scratch instead of the arena into the constructor
@@ -557,7 +572,7 @@ thread_ctx_init(){
//-----------------------------------------------------------------------------
template<class T>
struct Array{
Arena *allocator;
Allocator *allocator;
T *data;
S64 cap;
S64 len;
@@ -578,13 +593,14 @@ struct Array{
void grow(S64 required_size){
if(cap == 0){
S64 new_cap = max(required_size*2, (S64)16);
data = arena_push_array(allocator, T, new_cap);
data = allocate_array(allocator, T, new_cap);
cap = new_cap;
}
else if(len + required_size > cap){
U64 new_cap = max(cap * 2, len+required_size+1);
T *new_data = arena_push_array(allocator, T, new_cap);
T *new_data = allocate_array(allocator, T, new_cap);
memory_copy(new_data, data, cap*sizeof(T));
deallocate(allocator, data);
data = new_data;
cap = new_cap;
}
@@ -622,7 +638,7 @@ struct Array{
void init(Arena *a, S64 size = 16){
allocator = a;
data = arena_push_array(a, T, size);
data = allocate_array(a, T, size);
cap = size;
}
@@ -631,7 +647,7 @@ struct Array{
result.len = len;
result.cap = len*2;
result.allocator = a;
result.data = arena_push_array(a, T, result.cap);
result.data = allocate_array(a, T, result.cap);
memory_copy(result.data, data, sizeof(T)*result.len);
return result;
}
@@ -641,7 +657,7 @@ struct Array{
result.len = len;
result.cap = len;
result.allocator = 0;
result.data = arena_push_array(a, T, len);
result.data = allocate_array(a, T, len);
memory_copy(result.data, data, sizeof(T)*len);
return result;
}
@@ -731,7 +747,7 @@ struct Map_Key_Value{
};
struct Map{
Arena *allocator;
Allocator *allocator;
Map_Key_Value *data;
S64 len;
S64 cap;
@@ -746,7 +762,7 @@ map_grow(Map *map, S64 new_size){
assert(map->allocator);
Map new_map = {};
new_map.data = arena_push_array(map->allocator, Map_Key_Value, new_size, AF_ZeroMemory);
new_map.data = allocate_array(map->allocator, Map_Key_Value, new_size);
new_map.cap = new_size;
new_map.allocator = map->allocator;
@@ -755,7 +771,7 @@ map_grow(Map *map, S64 new_size){
map_insert(&new_map, map->data[i].key, map->data[i].value);
}
}
// if(map->data) exp_free(map->allocator, map->data);
if(map->data) deallocate(map->allocator, map->data);
*map = new_map;
}