Introduce the allocator stuff again
This commit is contained in:
72
base.cpp
72
base.cpp
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user