#pragma once // ::Allocator::Util::Header:: static inline usize CalcPaddingWithHeader(uintptr ptr, uintptr alignment, usize header_size); static inline usize CalcPadding(uintptr ptr, uintptr alignment); // ::Allocator::Arena::Header:: #define ARENA_HEADER_SIZE 64 typedef struct Arena { u8 *buffer; usize length; usize pos; u32 init_line_no; } Arena; typedef struct TempArena { Arena *arena; u64 pos; } TempArena; 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); // ::Allocator::GlobalAlloc::Header:: typedef struct AllocInfo { rawptr ptr; struct AllocInfo *next; } AllocInfo; typedef struct Allocator { RBTree *tree; RBTree *used_tree; HashTable *hash_table; rawptr buffer; u64 size; u64 free_size; u64 grow_size; } Allocator; static void InitAllocator(usize init_size); static void DeinitAlloc(); static void AllocGrow(usize size); static rawptr Alloc(usize size); static rawptr AllocAlign(usize size, usize alignment); static void Free(rawptr ptr); // ::Allocator::FreeList::Header:: typedef struct FLAllocHeader { usize size; usize padding; } FLAllocHeader; typedef struct FLNode { struct FLNode *next; usize size; } FLNode; typedef struct FreeList { rawptr data; FLNode *head; usize size; usize used; struct FreeList *next; } FreeList; typedef struct FLAlloc { FreeList *list_head; TicketMut mut; FLNode *nil; usize grow_size; } FLAlloc; static void GlobalFreeListInit(usize size); static rawptr FLMemAlloc(usize size); static rawptr FLMemAllocZeroed(usize size); static rawptr FLMemRealloc(rawptr old_ptr, usize size); static void FLMemFree(rawptr ptr); static usize FreeListPtrSize(FLAlloc *alloc, rawptr ptr); static void FreeListInit(FLAlloc *alloc, usize size); static rawptr FreeListAllocAlign(FLAlloc *alloc, usize size, usize alignment); static rawptr FreeListAlloc(FLAlloc *alloc, usize size); static void FreeListFree(FLAlloc *alloc, rawptr ptr); static void FreeListFreeAll(FLAlloc *alloc); static FreeList *FreeListGrow(FLAlloc *alloc, usize alloc_size); static rawptr FreeListRealloc(FLAlloc *alloc, rawptr old_ptr, usize size); static FLNode *FreeListSearch(FreeList *alloc, usize size, usize alignment, usize *out_padding, FLNode **prev_node); static void FreeListCoalescence(FreeList *alloc, FLNode *prev_node, FLNode *free_node); static void FreeListRemove(FLNode **head, FLNode *prev_node, FLNode *del_node); static void FreeListInsert(FLNode **head, FLNode *prev_node, FLNode *new_node); static FreeList *_FreeListFindList(FLAlloc *alloc, rawptr ptr); static void _FreeListInit(FreeList **alloc, usize size); static rawptr _FreeListAllocAlign(FreeList *alloc, usize size, usize alignment); static void _FreeListFree(FreeList *alloc, rawptr ptr);