diff --git a/src/allocators.c b/src/allocators.c index 212e604..dbbb771 100644 --- a/src/allocators.c +++ b/src/allocators.c @@ -6,17 +6,13 @@ read_only FLNode FL_NIL_NODE = {0}; // ::Allocator::Util::Header:: -usize CalcPaddingWithHeader(uintptr ptr, uintptr alignment, usize header_size) +static inline usize CalcPaddingWithHeader(uintptr ptr, uintptr alignment, usize header_size) { Assert(IsPow2(alignment), "Alignment provided to CalcPaddingWithHeader is not a power of two"); - uintptr modulo = ptr & (alignment-1); - uintptr padding = 0; + uintptr padding = CalcPadding(ptr, alignment); uintptr needed_space = (uintptr)header_size; - if (modulo != 0) - padding = alignment - modulo; - if (padding < needed_space) { needed_space -= padding; @@ -30,20 +26,44 @@ usize CalcPaddingWithHeader(uintptr ptr, uintptr alignment, usize header_size) return (usize)padding; } +static inline usize CalcPadding(uintptr ptr, uintptr alignment) +{ + Assert(IsPow2(alignment), "CalcPadding failure: IsPow2 failed"); + + uintptr padding = 0; + uintptr modulo = ptr & (alignment-1); + if (modulo != 0) + padding = alignment - modulo; + + return (usize)padding; +} + // ::Allocator::Arena::Start:: -static Arena *ArenaInit(rawptr buffer, usize length) +static Arena *ArenaInit(rawptr buffer, usize size) { Arena *arena = (Arena *)buffer; buffer = PtrAdd(buffer, ARENA_HEADER_SIZE); arena->buffer = buffer; - arena->length = length; + arena->length = size; arena->pos = 0; return arena; } +static Arena *ArenaCreate(usize size) +{ + u8 *mem = MemAllocZeroed(size); + return ArenaInit(mem, size); +} + +static Arena *ArenaCreateDebug(usize size, u32 init_line_no) +{ + u8 *mem = MemAllocZeroed(size); + return ArenaInitDebug(mem, size, init_line_no); +} + static rawptr ArenaAllocAlign(Arena *arena, usize size, usize align) { rawptr ptr = NULL; @@ -87,9 +107,9 @@ static void DeallocArena(Arena *arena) MemFree(arena, arena->length); } -static Arena * ArenaInitDebug(rawptr buffer, usize length, u32 init_line_no) +static Arena * ArenaInitDebug(rawptr buffer, usize size, u32 init_line_no) { - Arena *arena = ArenaInit(buffer, length); + Arena *arena = ArenaInit(buffer, size); arena->init_line_no = init_line_no; return arena; } @@ -112,49 +132,8 @@ static void InitAllocator(usize init_size) ALLOC.tree = FLMemAlloc(sizeof(RBTree)); RBTreeInit(ALLOC.tree); - - AllocInfo *info = CreateAllocInfo(ALLOC.buffer); - RBTreeFindOrInsert(ALLOC.tree, init_size, info); -} - -static AllocInfo *CreateAllocInfo(rawptr ptr) -{ - AllocInfo *info = FLMemAlloc(sizeof(AllocInfo)); - info->ptrs = FLMemAlloc(sizeof(rawptr *)); - info->ptrs[0] = ptr; - info->count = 1; -} - -static void AllocInfoAdd(AllocInfo *info, rawptr ptr) -{ - rawptr *ptrs = FLMemAlloc(sizeof(rawptr) * (info->count+1)); - MemCpy(ptrs, info->ptrs, sizeof(rawptr) * (info->count+1)); - FLMemFree(info->ptrs); - info->ptrs = ptrs; -} - -static void AllocInfoRemove(AllocInfo *info, rawptr ptr) -{ - u32 index = UINT32_MAX; - for (u32 i = 0; i < info->count; i++) - { - if (info->ptrs[i] == ptr) - { - index = i; - break; - } - } - - Assert(index != UINT32_MAX, "AllocInfoRemove called with invalid pointer"); - - rawptr *ptrs = FLMemAlloc(sizeof(rawptr) * (info->count-1)); - MemCpy(ptrs, info->ptrs, index); - MemCpy(&ptrs[index], &info->ptrs[index+1], info->count-index-1); - - FLMemFree(info->ptrs); - info->ptrs = ptrs; - info->count -= 1; + RBTreeInsert(ALLOC.tree, init_size, ALLOC.buffer); } static void DeinitAlloc() @@ -171,22 +150,29 @@ static rawptr AllocAlign(usize size, usize alignment) { if (size == 0) return NULL; - usize padding = 0; - - if (alignment < 8) - alignment = 8; - RBNode *node = P_RB_NIL; rawptr mem = NULL; - if (!RBTreeSearchNearest(ALLOC.tree, size, &node)) + if (!RBTreeSearchNearest(ALLOC.tree, size + alignment, &node)) { AllocGrow(size); - RBTreeSearchNearest(ALLOC.tree, size, &node); + RBTreeSearchNearest(ALLOC.tree, size + alignment, &node); } - + u64 alloc_size = node->key; + rawptr free_alloc = node->bucket.last->data; + RBTreeDelete(ALLOC.tree, alloc_size, free_alloc); + + usize padding = CalcPadding(uintptr(free_alloc), alignment); + uintptr new_addr = uintptr(free_alloc) + size + padding; + RBTreeInsert(ALLOC.tree, alloc_size - size - padding, rawptr(new_addr)); + + HashTablePushRawptrU64(ALLOC.hash_table, free_alloc, size + padding); + + return free_alloc; } +// TODO: finish allocator +// need an idea static void Free(rawptr ptr) { if (ptr == NULL) return; @@ -199,8 +185,7 @@ static void AllocGrow(usize size) usize grow_size = size < ALLOC.grow_size ? ALLOC.grow_size : ALLOC.grow_size + size; MemRealloc(ALLOC.buffer, ALLOC.size, ALLOC.size + grow_size); - AllocInfo *info = CreateAllocInfo(ALLOC.buffer + ALLOC.size); // TODO: check this if things fuck up it could be wrong - RBTreeFindOrInsert(ALLOC.tree, grow_size, info); + RBTreeInsert(ALLOC.tree, grow_size, ALLOC.buffer + ALLOC.size); // TODO: check this if things fuck up it could be wrong ALLOC.size += grow_size; ALLOC.free_size += grow_size; @@ -341,7 +326,7 @@ static void FreeListGrow(FLAlloc *alloc, usize alloc_size) alloc->lists[i]->head = node; } -static rawptr _FreeListAllocAlign(FreeList *alloc, usize size, u32 alignment) +static rawptr _FreeListAllocAlign(FreeList *alloc, usize size, usize alignment) { if (size == 0) return NULL; @@ -388,7 +373,7 @@ static rawptr FreeListAlloc(FLAlloc *alloc, usize size) return FreeListAllocAlign(alloc, size, DEFAULT_ALIGNMENT); } -static rawptr FreeListAllocAlign(FLAlloc *alloc, usize size, u32 alignment) +static rawptr FreeListAllocAlign(FLAlloc *alloc, usize size, usize alignment) { u32 ticket = __atomic_fetch_add(&alloc->ticket, 1, __ATOMIC_SEQ_CST); while (ticket != alloc->next_ticket); diff --git a/src/allocators.h b/src/allocators.h index 6c000ed..d09f2e6 100644 --- a/src/allocators.h +++ b/src/allocators.h @@ -2,7 +2,8 @@ // ::Allocator::Util::Header:: -usize CalcPaddingWithHeader(uintptr ptr, uintptr alignment, usize header_size); +static inline usize CalcPaddingWithHeader(uintptr ptr, uintptr alignment, usize header_size); +static inline usize CalcPadding(uintptr ptr, uintptr alignment); // ::Allocator::Arena::Header:: @@ -22,13 +23,15 @@ typedef struct TempArena u64 pos; } TempArena; -static Arena *ArenaInit(rawptr buffer, usize length); +static Arena *ArenaInit(rawptr buffer, usize size); +static Arena *ArenaCreate(usize size); +static Arena *ArenaCreateDebug(usize size, u32 init_line_no); +static Arena *ArenaInitDebug(rawptr buffer, usize size, u32 init_line_no); static rawptr ArenaAllocAlign(Arena *arena, usize size, usize align); static rawptr ArenaAlloc(Arena *arena, usize size); static void ArenaFree(Arena *arena); static void ArenaFreeZeroed(Arena *arena); static void DeallocArena(Arena *arena); -static Arena *ArenaInitDebug(rawptr buffer, usize length, u32 init_line_no); // ::Allocator::GlobalAlloc::Header:: @@ -50,9 +53,6 @@ typedef struct Allocator } Allocator; static void InitAllocator(usize init_size); -static AllocInfo *CreateAllocInfo(rawptr ptr); -static void AllocInfoAdd(AllocInfo *info, rawptr ptr); -static void AllocInfoRemove(AllocInfo *info, rawptr ptr); static void DeinitAlloc(); static void AllocGrow(usize size); static rawptr Alloc(usize size); @@ -98,8 +98,8 @@ static rawptr FLMemAllocZeroed(usize size); static void FLMemFree(rawptr ptr); static void _FreeListInit(FreeList **alloc, usize size); static void FreeListInit(FLAlloc *alloc, usize size); -static rawptr _FreeListAllocAlign(FreeList *alloc, usize size, u32 alignment); -static rawptr FreeListAllocAlign(FLAlloc *alloc, usize size, u32 alignment); +static rawptr _FreeListAllocAlign(FreeList *alloc, usize size, usize alignment); +static rawptr FreeListAllocAlign(FLAlloc *alloc, usize size, usize alignment); static rawptr FreeListAlloc(FLAlloc *alloc, usize size); static void _FreeListFree(FreeList *alloc, rawptr ptr); static void FreeListFree(FLAlloc *alloc, rawptr ptr); diff --git a/src/assets.h b/src/assets.h index 273d943..bbcd90b 100644 --- a/src/assets.h +++ b/src/assets.h @@ -55,4 +55,5 @@ typedef enum ModelAssetTag_e MODEL_ASSET_TAG_MAX, } ModelAssetTag; - +static rawptr LoadTextureAsset(TextureAsset asset_id); +static rawptr LoadShaderAsset(ShaderAsset asset_id); diff --git a/src/ds.c b/src/ds.c index 56c3b08..ad96d32 100644 --- a/src/ds.c +++ b/src/ds.c @@ -32,7 +32,7 @@ static inline void RBTreePushDataNode(RBDataNode *first, RBDataNode *last, rawpt RBQueuePush(first, last, data_node); } -static inline RBNode *RBTreeInitNode(u32 key, rawptr value) +static inline RBNode *RBTreeInitNode(u64 key, rawptr value) { RBNode *node = FLMemAllocZeroed(sizeof(RBNode)); node->parent = node->left = node->right = P_RB_NIL; @@ -44,9 +44,9 @@ static inline RBNode *RBTreeInitNode(u32 key, rawptr value) return node; } -static void RBTreeInsert(RBTree *tree, u32 key, rawptr value) +static void RBTreeInsert(RBTree *tree, u64 key, rawptr value) { - RBNode *existing_node = P_RB_NIL; + RBNode *node = P_RB_NIL; node->left = node->right = tree->nil; node->color = RB_RED; @@ -66,14 +66,14 @@ static void RBTreeInsert(RBTree *tree, u32 key, rawptr value) if (curr_node->key == key) { - RBTreeInitDataNode(curr_node->bucket.first, curr_node->bucket.last, value); + RBTreePushDataNode(curr_node->bucket.first, curr_node->bucket.last, value); break; } else if (curr_node->key < key) { if (curr_node->right == tree->nil) { - RBNode *node = RBTreeInitNode(key, value); + node = RBTreeInitNode(key, value); node->parent = curr_node; curr_node->right = node; break; @@ -87,7 +87,7 @@ static void RBTreeInsert(RBTree *tree, u32 key, rawptr value) { if (curr_node->left == tree->nil) { - RBNode *node = RBTreeInitNode(key, value); + node = RBTreeInitNode(key, value); node->parent = curr_node; curr_node->left = node; break; @@ -100,7 +100,7 @@ static void RBTreeInsert(RBTree *tree, u32 key, rawptr value) } } - if (node->parent->color != RB_BLACK && existing_node != P_RB_NIL) + if (node->parent->color != RB_BLACK && node != P_RB_NIL) RBTreeCorrect(tree, node); } @@ -147,12 +147,12 @@ static void RBTreeCorrect(RBTree *tree, RBNode *node) } while ((p = node->parent)); } -static void RBTreeDelete(RBTree *tree, u32 key, rawptr value) +static void RBTreeDelete(RBTree *tree, u64 key, rawptr value) { RBNode *node = NULL; Assert(RBTreeSearch(tree, key, &node), "Unable to find node in RBTreeDelete"); - if (node->bucket.first.data != value) + if (node->bucket.first->data != value) { Assert(node->bucket.first->next != P_RB_DN_NIL, "RBTreeDelete Failure: unable to find value to delete"); RBDataNode *data_node = node->bucket.first->next; @@ -186,7 +186,7 @@ static void RBTreeDelete(RBTree *tree, u32 key, rawptr value) ln = ln->left; node->key = ln->key; - node->data = ln->data; + node->bucket = ln->bucket; if (node->right == ln) node->right = tree->nil; @@ -198,13 +198,13 @@ static void RBTreeDelete(RBTree *tree, u32 key, rawptr value) else if (node->color == RB_BLACK && node->left != tree->nil) { node->key = node->left->key; - node->data = node->left->data; + node->bucket = node->left->bucket; node->left = tree->nil; } else if (node->color == RB_BLACK && node->right != tree->nil) { node->key = node->right->key; - node->data = node->right->data; + node->bucket = node->right->bucket; node->right = tree->nil; } else if (node->color == RB_RED && node->right == tree->nil && node->left == tree->nil) @@ -286,20 +286,21 @@ static void RBTreeDelete(RBTree *tree, u32 key, rawptr value) } } -static b32 RBTreeSearchNearest(RBTree *tree, u32 key, RBNode **out_node) +static b32 RBTreeSearchNearest(RBTree *tree, u64 key, RBNode **out_node) { if (tree->root == tree->nil) return false; RBNode *node = tree->root; RBNode *nearest = tree->root; - u32 nearest_diff = UINT32_MAX; + u64 nearest_diff = UINT64_MAX; while (true) { if (node == tree->nil) break; - u32 diff = Abs(node->key - key); + u64 diff = node->key - key; + diff = Abs(diff); if (diff == 0) { @@ -324,7 +325,7 @@ static b32 RBTreeSearchNearest(RBTree *tree, u32 key, RBNode **out_node) return *out_node != tree->nil; } -static b32 RBTreeSearch(RBTree *tree, u32 key, RBNode **out_node) +static b32 RBTreeSearch(RBTree *tree, u64 key, RBNode **out_node) { if (tree->root == tree->nil) return false; @@ -477,30 +478,36 @@ static HashNode *HashTablePush(HashTable *table, u64 hash, KeyValuePair value) return node; } -static HashNode *HashTablePushU32(HashTable *table, u64 key, u32 value) +static HashNode *HashTablePushU64U32(HashTable *table, u64 key, u32 value) { u64 hash = HashFromString(String8Struct(&key)); return HashTablePush(table, hash, (KeyValuePair){ .key_u64 = key, .value_u32 = value }); } -static HashNode *HashTablePushU64(HashTable *table, u64 key, u64 value) +static HashNode *HashTablePushU64U64(HashTable *table, u64 key, u64 value) { u64 hash = HashFromString(String8Struct(&key)); return HashTablePush(table, hash, (KeyValuePair){ .key_u64 = key, .value_u64 = value }); } -static HashNode *HashTablePushString8(HashTable *table, u64 key, String8 value) +static HashNode *HashTablePushU64String8(HashTable *table, u64 key, String8 value) { u64 hash = HashFromString(String8Struct(&key)); return HashTablePush(table, hash, (KeyValuePair){ .key_u64 = key, .value_string = value }); } -static HashNode *HashTablePushRawptr(HashTable *table, u64 key, rawptr value) +static HashNode *HashTablePushU64Rawptr(HashTable *table, u64 key, rawptr value) { u64 hash = HashFromString(String8Struct(&key)); return HashTablePush(table, hash, (KeyValuePair){ .key_u64 = key, .value_rawptr = value }); } +static HashNode *HashTablePushRawptrU64(HashTable *table, rawptr key, u64 value) +{ + u64 hash = HashFromString(String8Struct(&key)); + return HashTablePush(table, hash, (KeyValuePair){ .key_rawptr = key, .value_u64 = value }); +} + static KeyValuePair *HashTableSearchU64(HashTable *table, u64 key) { KeyValuePair *result = NULL; @@ -520,6 +527,25 @@ static KeyValuePair *HashTableSearchU64(HashTable *table, u64 key) return result; } +static KeyValuePair *HashTableSearchRawptr(HashTable *table, rawptr key) +{ + KeyValuePair *result = NULL; + + u64 hash = HashFromString(String8Struct(&key)); + u64 index = hash % table->cap; + HashList *list = table->lists + index; + for (HashNode *node = list->first; node != P_HT_NIL; node = node->next) + { + if (node->v.key_rawptr == key) + { + result = &node->v; + break; + } + } + + return result; +} + // ::DataStructures::HashTable::Functions::End:: diff --git a/src/ds.h b/src/ds.h index 5a934f7..9e2fe5b 100644 --- a/src/ds.h +++ b/src/ds.h @@ -43,7 +43,7 @@ typedef struct RBNode struct RBNode *child[2]; }; struct RBNode *parent; - u32 key; + u64 key; RBBucket bucket; RBNodeColor color; } RBNode; @@ -55,12 +55,12 @@ typedef struct RBTree } RBTree; static void RBTreeInit (RBTree *tree); -static inline RBNode *RBTreeInitNode(u32 key, rawptr value); +static inline RBNode *RBTreeInitNode(u64 key, rawptr value); static inline void RBTreePushDataNode(RBDataNode *first, RBDataNode *last, rawptr value); -static RBNode *RBTreeFindOrInsert(RBTree *tree, u32 key, rawptr value); -static b32 RBTreeSearchNearest(RBTree *tree, u32 key, RBNode **node); -static b32 RBTreeSearch (RBTree *tree, u32 key, RBNode **node); -static void RBTreeDelete (RBTree *tree, u32 key, rawptr value); +static void RBTreeInsert(RBTree *tree, u64 key, rawptr value); +static b32 RBTreeSearchNearest(RBTree *tree, u64 key, RBNode **node); +static b32 RBTreeSearch (RBTree *tree, u64 key, RBNode **node); +static void RBTreeDelete (RBTree *tree, u64 key, rawptr value); static void RBTreeLeftRotate (RBTree *tree, RBNode *node); static void RBTreeRightRotate(RBTree *tree, RBNode *node); static void RBTreeRotate (RBTree *tree, RBNode *node, RBNodeDir dir); @@ -77,14 +77,15 @@ typedef struct KeyValuePair { union { - u64 key_u64; + u64 key_u64; + rawptr key_rawptr; }; union { - String8 value_string; - rawptr value_rawptr; - u32 value_u32; - u64 value_u64; + String8 value_string; + rawptr value_rawptr; + u32 value_u32; + u64 value_u64; }; } KeyValuePair; @@ -114,9 +115,10 @@ static void HashTableConcatInPlace(HashList *list, HashList *to_concat); static u64 HashTableHash(String8 str); static HashNode *HashListPop(HashList *list); static KeyValuePair *HashTableSearchU64(HashTable *table, u64 key); +static KeyValuePair *HashTableSearchRawptr(HashTable *table, rawptr key); static HashNode *HashTablePush(HashTable *table, u64 hash, KeyValuePair value); -static HashNode *HashTablePushU32(HashTable *table, u64 key, u32 value); -static HashNode *HashTablePushU64(HashTable *table, u64 key, u64 value); -static HashNode *HashTablePushString8(HashTable *table, u64 key, String8 value); -static HashNode *HashTablePushRawptr(HashTable *table, u64 key, rawptr value); +static HashNode *HashTablePushU64U32(HashTable *table, u64 key, u32 value); +static HashNode *HashTablePushU64U64(HashTable *table, u64 key, u64 value); +static HashNode *HashTablePushU64String8(HashTable *table, u64 key, String8 value); +static HashNode *HashTablePushU64Rawptr(HashTable *table, u64 key, rawptr value); diff --git a/src/entry_linux.c b/src/entry_linux.c index 88e0956..c92b901 100644 --- a/src/entry_linux.c +++ b/src/entry_linux.c @@ -9,8 +9,8 @@ #include "fastlz/fastlz.c" #include "platform/platform.c" -#include "ds.c" #include "util.c" +#include "ds.c" #include "allocators.c" #include "renderer.c" #include "game.c" @@ -58,17 +58,9 @@ int main(int argc, char **argv) return 0; #endif - u8 *mem = (u8 *)MemAllocZeroed(MB(64)); - Arena *arena = ArenaInitDebug(mem, MB(64), __LINE__); - - usize renderer_mem_size = MB(16); - usize game_mem_size = MB(16); - - rawptr renderer_mem = ArenaAlloc(arena, renderer_mem_size); - Arena *renderer_arena = ArenaInitDebug(renderer_mem, renderer_mem_size, 2); - - rawptr game_mem = ArenaAlloc(arena, game_mem_size); - Arena *game_arena = ArenaInitDebug(game_mem, game_mem_size, 3); + Arena *arena = ArenaCreateDebug(MB(32), __LINE__); + Arena *renderer_arena = ArenaCreateDebug(MB(16), __LINE__); + Arena *game_arena = ArenaCreateDebug(MB(16), __LINE__); Assert(CreatePlatformWindow(WINDOW_NAME), "Failed to initialize the window"); diff --git a/src/entry_linux.h b/src/entry_linux.h index 87c687a..113499e 100644 --- a/src/entry_linux.h +++ b/src/entry_linux.h @@ -14,9 +14,9 @@ #include "fastlz/fastlz.h" #include "shared_types.h" +#include "util.h" #include "ds.h" #include "platform/platform.h" -#include "util.h" #include "allocators.h" #include "renderer.h" #include "game.h" diff --git a/src/tests.c b/src/tests.c index 80b514f..20582d7 100644 --- a/src/tests.c +++ b/src/tests.c @@ -2,7 +2,6 @@ void RunTests() { - GlobalFreeListInit(MB(32)); TestFreeListAlloc(); TestHashTable(); } @@ -60,7 +59,7 @@ void TestHashTable() for (u64 i = 1; i < 2000; i++) { - HashTablePushU64(&table, i*3, i); + HashTablePushU64U64(&table, i*3, i); } for (u64 i = 1; i < 2000; i++) diff --git a/src/util.c b/src/util.c index 362b1da..a072ea7 100644 --- a/src/util.c +++ b/src/util.c @@ -169,6 +169,7 @@ void MemCpy(rawptr dst, rawptr src, usize size) DefMathImpl(Min); DefMathImpl(Max); DefMathImpl(Clamp); +DefMathImpl(Abs); // ::Util::Math::Functions::End::