platform_arena.h (3802B)
1 ////////////////////////////////////////////////////////////////// 2 // platform_arena.h 3 4 ////////////////////////////////////////////////////////////////// 5 // Constants 6 7 #define RV_ARENA_HEADER_SIZE 128 8 9 ////////////////////////////////////////////////////////////////// 10 // Types 11 12 typedef u64 rv_arena_flags; 13 enum { 14 rv_arena_flag_no_chain = (1<<0), 15 rv_arena_flag_large_pages = (1<<1), 16 }; 17 18 typedef struct rv_arena_params rv_arena_params; 19 struct rv_arena_params { 20 rv_arena_flags flags; 21 u64 reserve_size; 22 u64 commit_size; 23 void *optional_backing_buffer; 24 }; 25 26 typedef struct rv_arena rv_arena; 27 struct rv_arena 28 { 29 rv_arena *prev; // previous arena in chain 30 rv_arena *current; // current arena in chain 31 rv_arena_flags flags; 32 u64 cmt_size; 33 u64 res_size; 34 u64 base_pos; 35 u64 pos; 36 u64 cmt; 37 u64 res; 38 #if RV_ARENA_FREE_LIST 39 u64 free_size; 40 rv_arena *free_last; 41 #endif 42 }; 43 //StaticAssert(sizeof(rv_arena) <= RV_ARENA_HEADER_SIZE, arena header too large); 44 45 typedef struct rv_temp_arena rv_temp_arena; 46 struct rv_temp_arena 47 { 48 rv_arena *arena; 49 u64 pos; 50 }; 51 52 ////////////////////////////////////////////////////////////////// 53 // Global Defaults 54 55 RV_GLOBAL u64 rv_arena_default_reserve_size = MB(64); 56 RV_GLOBAL u64 rv_arena_default_commit_size = KB(64); 57 RV_GLOBAL rv_arena_flags rv_arena_default_flags = 0; 58 59 ////////////////////////////////////////////////////////////////// 60 // Arena Functions 61 62 // Arena Creation/Destruction 63 RV_INTERNAL rv_arena* rv_arena_alloc_(rv_arena_params* params); 64 #define rv_arena_alloc(...) rv_arena_alloc_(&(rv_arena_params){.reserve_size = rv_arena_default_reserve_size, .commit_size = rv_arena_default_commit_size, .flags = rv_arena_default_flags, __VA_ARGS__}) 65 RV_INTERNAL void rv_arena_release(rv_arena* arena); 66 67 // Arena Push/Pop/Pos Core Functions 68 RV_INTERNAL void* rv_arena_push(rv_arena* arena, u64 size, u64 align); 69 RV_INTERNAL u64 rv_arena_pos(rv_arena* arena); 70 RV_INTERNAL void rv_arena_pop_to(rv_arena* arena, u64 pos); 71 72 // Arena Push/Pop Helpers 73 RV_INTERNAL void rv_arena_clear(rv_arena* arena); 74 RV_INTERNAL void rv_arena_pop(rv_arena* arena, u64 amt); 75 76 // Temporary Arena Scopes 77 RV_INTERNAL rv_temp_arena rv_temp_begin(rv_arena* arena); 78 RV_INTERNAL void rv_temp_end(rv_temp_arena temp); 79 80 // Push Helper Macros 81 #define rv_push_no_zero_aligned(a, T, align) (T*)rv_arena_push((a), sizeof(T), (align)) 82 #define rv_push_no_zero(a, T) rv_push_no_zero_aligned(a, T, rv_alignof(T)) 83 #define rv_push_aligned(a, T, align) (T*)rv_mem_zero(rv_push_no_zero_aligned(a, T, align), sizeof(T)) 84 #define rv_push(a, T) rv_push_aligned(a, T, rv_alignof(T)) 85 86 #define rv_push_compound(a, T, ...) rv_mem_copy(rv_push_no_zero_aligned(a, T, rv_alignof(T)), &(T)__VA_ARGS__, sizeof(T)) 87 #define rv_push_copy(a, T, v) rv_mem_copy(rv_push_no_zero_aligned(a, T, rv_alignof(T)), (T*)v, sizeof(T)) 88 89 #define rv_push_array_no_zero_aligned(a, T, c, align) (T*)rv_arena_push((a), sizeof(T)*(c), (align)) 90 #define rv_push_array_no_zero(a, T, c) rv_push_array_no_zero_aligned(a, T, c, rv_alignof(T)) 91 #define rv_push_array_aligned(a, T, c, align) (T*)rv_mem_zero(rv_push_array_no_zero_aligned(a, T, c, align), sizeof(T)*(c)) 92 #define rv_push_array(a, T, c) rv_push_array_aligned(a, T, c, rv_alignof(T)) 93 94 #define rv_push_array_compound(a, T, c, ...) rv_mem_copy(rv_push_array_no_zero_aligned(a, T, c, rv_alignof(T)), (T[c])__VA_ARGS__, sizeof(T)*c) 95 #define rv_push_array_copy(a, T, c, v) rv_mem_copy(rv_push_array_no_zero_aligned(a, T, c, rv_alignof(T)), (T*)v, sizeof(T) * (c)) 96 97 // Scratch 98 RV_GLOBAL rv_arena* rv_scratch_begin_(rv_arena **conflicts, u64 count); 99 #define rv_scratch_begin(conflicts, count) rv_temp_begin(rv_scratch_begin_((conflicts), (count))); 100 #define rv_scratch_end(scratch) (rv_temp_end(scratch), scratch = (rv_temp_arena){0})