From 2bbc49242e2f1bfa91532dc794ae82ce777f1031 Mon Sep 17 00:00:00 2001 From: doyle Date: Thu, 6 Jul 2023 21:13:52 +1000 Subject: [PATCH] dqn: Cleanup more documentation --- dqn_containers.h | 127 +++++++++++++++++++------------------ dqn_core.h | 40 ++++++------ dqn_hash.h | 18 +++--- dqn_math.cpp | 30 ++++----- dqn_math.h | 61 +++++++++++++----- dqn_memory.h | 159 +++++++++++++++++++++-------------------------- 6 files changed, 227 insertions(+), 208 deletions(-) diff --git a/dqn_containers.h b/dqn_containers.h index 9794854..34af4cc 100644 --- a/dqn_containers.h +++ b/dqn_containers.h @@ -15,7 +15,7 @@ // possibly ever need (e.g. 16GB) and let the array commit physical pages on // demand. On 64 bit operating systems you are given 48 bits of addressable // space giving you 256 TB of reservable memory. This gives you practically -// an unlimited array capacity that avoids reallocs and only consumes memory +// an unlimited array capacity that avoids reallocs and only consumes memory // that is actually occupied by the array. // // Each page that is committed into the array will be at page/allocation @@ -28,24 +28,26 @@ // // In addition to no realloc on expansion or shrinking. // -// NOTE: API +// TODO(doyle): Add an API for shrinking the array by decomitting pages back to +// the OS. // +// NOTE: API // @proc Dqn_VArray_InitByteSize, Dqn_VArray_Init // @desc Initialise an array with the requested byte size or item capacity // respectively. The returned array may have a higher capacity than the // requested amount since requested memory from the OS may have a certain // alignment requirement (e.g. on Windows reserve/commit are 64k/4k aligned). -// + // @proc Dqn_VArray_IsValid // @desc Verify if the array has been initialised -// + // @proc Dqn_VArray_Make, Dqn_VArray_Add // @desc Allocate items into the array // 'Make' creates the `count` number of requested items // 'Add' adds the array of items into the array // @return The array of items allocated. Null pointer if the array is invalid // or the array has insufficient space for the requested items. -// + // @proc Dqn_VArray_EraseRange // @desc Erase the next `count` items at `begin_index` in the array. `count` // can be positive or negative which dictates the if we erase forward from the @@ -56,10 +58,10 @@ // @param erase The erase method, stable erase will shift all elements after // the erase ranged into the range. Unstable erase will copy the tail elements // into the range to delete. -// + // @proc Dqn_VArray_Clear // @desc Set the size of the array to 0 -// + // @proc Dqn_VArray_Reserve // @desc Ensure that the requested number of items are backed by physical // pages from the OS. Calling this pre-emptively will minimise syscalls into @@ -67,17 +69,13 @@ // in bytes to the allocation granularity of OS allocation APIs hence the // reserved space may be greater than the requested amount (e.g. this is 4k // on Windows). -// -// TODO(doyle) -// -// Add an API for shrinking the array by decomitting pages back to the OS. template struct Dqn_VArray { - Dqn_ArenaBlock *block; ///< Block of memory from the allocator for this array - T *data; ///< Pointer to the start of the array items in the block of memory - Dqn_usize size; ///< Number of items currently in the array - Dqn_usize max; ///< Maximum number of items this array can store + Dqn_ArenaBlock *block; // Block of memory from the allocator for this array + T *data; // Pointer to the start of the array items in the block of memory + Dqn_usize size; // Number of items currently in the array + Dqn_usize max; // Maximum number of items this array can store T *begin() { return data; } T *end () { return data + size; } @@ -91,14 +89,19 @@ enum Dqn_VArrayErase Dqn_VArrayErase_Stable, }; -DQN_API template Dqn_VArray Dqn_VArray_InitByteSize(Dqn_Arena *arena, Dqn_usize byte_size); -DQN_API template Dqn_VArray Dqn_VArray_Init (Dqn_Arena *arena, Dqn_usize max); -DQN_API template bool Dqn_VArray_IsValid (Dqn_VArray const *array); -DQN_API template T * Dqn_VArray_Make (Dqn_VArray *array, Dqn_usize count, Dqn_ZeroMem zero_mem); -DQN_API template T * Dqn_VArray_Add (Dqn_VArray *array, T const *items, Dqn_usize count); -DQN_API template void Dqn_VArray_EraseRange (Dqn_VArray *array, Dqn_usize begin_index, Dqn_isize count, Dqn_VArrayErase erase); -DQN_API template void Dqn_VArray_Clear (Dqn_VArray *array); -DQN_API template void Dqn_VArray_Reserve (Dqn_VArray *array, Dqn_usize count); +// NOTE: Setup ===================================================================================== +DQN_API template Dqn_VArray Dqn_VArray_InitByteSize(Dqn_Arena *arena, Dqn_usize byte_size); +DQN_API template Dqn_VArray Dqn_VArray_Init (Dqn_Arena *arena, Dqn_usize max); +DQN_API template bool Dqn_VArray_IsValid (Dqn_VArray const *array); +DQN_API template void Dqn_VArray_Reserve (Dqn_VArray *array, Dqn_usize count); + +// NOTE: Insert ==================================================================================== +DQN_API template T * Dqn_VArray_Make (Dqn_VArray *array, Dqn_usize count, Dqn_ZeroMem zero_mem); +DQN_API template T * Dqn_VArray_Add (Dqn_VArray *array, T const *items, Dqn_usize count); + +// NOTE: Modify ==================================================================================== +DQN_API template void Dqn_VArray_EraseRange (Dqn_VArray *array, Dqn_usize begin_index, Dqn_isize count, Dqn_VArrayErase erase); +DQN_API template void Dqn_VArray_Clear (Dqn_VArray *array); #endif // !defined(DQN_NO_VARRAY) #if !defined(DQN_NO_DSMAP) @@ -149,27 +152,27 @@ DQN_API template void Dqn_VArray_Reserve (Dqn_VArray< // // - Functions that return a pointer or boolean will always return null or false // if the passed in map is invalid e.g. `DSMap_IsValid()` returns false. -// + // @proc Dqn_DSMap_Init // @param size[in] The number of slots in the table. This size must be a // power-of-two or otherwise an assert will be triggered. // @return The hash table. On memory allocation failure, the table will be // zero initialised whereby calling Dqn_DSMap_IsValid() will return false. -// + // @proc Dqn_DSMap_Deinit // @desc Free the memory allocated by the table -// + // @proc Dqn_DSMap_IsValid // @desc Verify that the table is in a valid state (e.g. initialised // correctly). -// + // @proc Dqn_DSMap_Hash // @desc Hash the input key using the custom hash function if it's set on the // map, otherwise uses the default hashing function (32bit Murmur3). // // @proc Dqn_DSMap_HashToSlotIndex // @desc Calculate the index into the map's `slots` array from the given hash. -// + // @proc Dqn_DSMap_FindSlot, Dqn_DSMap_Find // @desc Find the slot in the map's `slots` array corresponding to the given // key and hash. If the map does not contain the key, a null pointer is @@ -177,7 +180,7 @@ DQN_API template void Dqn_VArray_Reserve (Dqn_VArray< // // `Find` returns the value. // `FindSlot` returns the map's hash table slot. -// + // @proc Dqn_DSMap_MakeSlot, Dqn_DSMap_Make, Dqn_DSMap_Set, Dqn_DSMap_SetSlot // @desc Same as `DSMap_Find*` except if the key does not exist in the table, // a hash-table slot will be made. @@ -194,20 +197,20 @@ DQN_API template void Dqn_VArray_Reserve (Dqn_VArray< // @param found[out] Pass a pointer to a bool. The bool will be set to true // if the item already existed in the map before, or false if the item was // just created by this call. -// + // @proc Dqn_DSMap_Resize // @desc Resize the table and move all elements to the new map. // the elements currently set in the // @param size[in] New size of the table, must be a power of two. // @return False if memory allocation fails, or the requested size is smaller // than the current number of elements in the map to resize. True otherwise. -// + // @proc Dqn_DSMap_Erase // @desc Remove the key-value pair from the table. If by erasing the key-value // pair from the table puts the table under 25% load, the table will be shrunk // by 1/2 the current size after erasing. The table will not shrink below the // initial size that the table was initialised as. -// + // @proc Dqn_DSMap_KeyCStringLit, Dqn_DSMap_KeyU64, Dqn_DSMap_KeyBuffer, // Dqn_DSMap_KeyString8 Dqn_DSMap_KeyString8Copy // @desc Create a hash-table key given @@ -221,7 +224,7 @@ DQN_API template void Dqn_VArray_Reserve (Dqn_VArray< // If the key points to an array of bytes, the lifetime of those bytes *must* // remain valid throughout the lifetime of the map as the pointers are value // copied into the hash table! -// + // @proc Dqn_DSMap_KeyU64NoHash // @desc Create a hash-table key given the uint64. This u64 is *not* hashed to // map values into the table. This is useful if you already have a source of @@ -234,9 +237,9 @@ DQN_API template void Dqn_VArray_Reserve (Dqn_VArray< enum Dqn_DSMapKeyType { Dqn_DSMapKeyType_Invalid, - Dqn_DSMapKeyType_U64, ///< Use a U64 key that is `hash(u64) % size` to map into the table - Dqn_DSMapKeyType_U64NoHash, ///< Use a U64 key that is `u64 % size` to map into the table - Dqn_DSMapKeyType_Buffer, ///< Use a buffer key that is `hash(buffer) % size` to map into the table + Dqn_DSMapKeyType_U64, // Use a U64 key that is `hash(u64) % size` to map into the table + Dqn_DSMapKeyType_U64NoHash, // Use a U64 key that is `u64 % size` to map into the table + Dqn_DSMapKeyType_Buffer, // Use a buffer key that is `hash(buffer) % size` to map into the table }; struct Dqn_DSMapKey @@ -261,14 +264,14 @@ template struct Dqn_DSMapSlot using Dqn_DSMapHashFunction = uint32_t(Dqn_DSMapKey key, uint32_t seed); template struct Dqn_DSMap { - uint32_t *hash_to_slot; ///< Mapping from hash to a index in the slots array - Dqn_DSMapSlot *slots; ///< Values of the array stored contiguously, non-sorted order - uint32_t size; ///< Total capacity of the map and is a power of two - uint32_t occupied; ///< Number of slots used in the hash table - Dqn_Allocator allocator; ///< Backing allocator for the hash table - uint32_t initial_size; ///< Initial map size, map cannot shrink on erase below this size - Dqn_DSMapHashFunction *hash_function; ///< Custom hashing function to use if field is set - uint32_t hash_seed; ///< Seed for the hashing function, when 0, DQN_DS_MAP_DEFAULT_HASH_SEED is used + uint32_t *hash_to_slot; // Mapping from hash to a index in the slots array + Dqn_DSMapSlot *slots; // Values of the array stored contiguously, non-sorted order + uint32_t size; // Total capacity of the map and is a power of two + uint32_t occupied; // Number of slots used in the hash table + Dqn_Allocator allocator; // Backing allocator for the hash table + uint32_t initial_size; // Initial map size, map cannot shrink on erase below this size + Dqn_DSMapHashFunction *hash_function; // Custom hashing function to use if field is set + uint32_t hash_seed; // Seed for the hashing function, when 0, DQN_DS_MAP_DEFAULT_HASH_SEED is used }; // NOTE: Setup ===================================================================================== @@ -305,8 +308,8 @@ DQN_API bool operator== (Dqn_DS // NOTE: [$FARR] Dqn_FArray ======================================================================== template struct Dqn_FArray { - T data[N]; ///< Pointer to the start of the array items in the block of memory - Dqn_usize size; ///< Number of items currently in the array + T data[N]; // Pointer to the start of the array items in the block of memory + Dqn_usize size; // Number of items currently in the array T *begin() { return data; } T *end () { return data + size; } @@ -320,35 +323,40 @@ enum Dqn_FArrayErase Dqn_FArrayErase_Stable, }; +// NOTE: Setup ===================================================================================== DQN_API template Dqn_FArray Dqn_FArray_Init (T const *array, Dqn_usize count); DQN_API template bool Dqn_FArray_IsValid (Dqn_FArray const *array); + +// NOTE: Insert ==================================================================================== DQN_API template T * Dqn_FArray_Make (Dqn_FArray *array, Dqn_usize count, Dqn_ZeroMem zero_mem); DQN_API template T * Dqn_FArray_Add (Dqn_FArray *array, T const *items, Dqn_usize count); + +// NOTE: Modify ==================================================================================== DQN_API template void Dqn_FArray_EraseRange(Dqn_FArray *array, Dqn_usize begin_index, Dqn_isize count, Dqn_FArrayErase erase); DQN_API template void Dqn_FArray_Clear (Dqn_FArray *array); #endif // !defined(DQN_NO_FARRAY) #if !defined(DQN_NO_LIST) // NOTE: [$LIST] Dqn_List ========================================================================== -// NOTE: API // +// NOTE: API // @proc Dqn_List_At // @param at_chunk[out] (Optional) The chunk that the index belongs to will // be set in this parameter if given // @return The element, or null pointer if it is not a valid index. -// + // @proc Dqn_List_Iterate // @desc Produce an iterator for the data in the list // // @param[in] start_index The index to start iterating from // -// @begincode -// Dqn_List list = {}; -// for (Dqn_ListIterator it = {}; Dqn_List_Iterate(&list, &it, 0);) -// { -// int *item = it.data; -// } -// @endcode +#if 0 + Dqn_List list = {}; + for (Dqn_ListIterator it = {}; Dqn_List_Iterate(&list, &it, 0);) + { + int *item = it.data; + } +#endif template struct Dqn_ListChunk { @@ -361,10 +369,10 @@ template struct Dqn_ListChunk template struct Dqn_ListIterator { - Dqn_b32 init; // (Internal): True if Dqn_List_Iterate has been called at-least once on this iterator - Dqn_ListChunk *chunk; // (Internal): The chunk that the iterator is reading from - Dqn_usize chunk_data_index; // (Internal): The index in the chunk the iterator is referencing - T *data; // (Read): Pointer to the data the iterator is referencing. Nullptr if invalid. + Dqn_b32 init; // True if Dqn_List_Iterate has been called at-least once on this iterator + Dqn_ListChunk *chunk; // The chunk that the iterator is reading from + Dqn_usize chunk_data_index; // The index in the chunk the iterator is referencing + T *data; // Pointer to the data the iterator is referencing. Nullptr if invalid. }; template struct Dqn_List @@ -1064,4 +1072,3 @@ template DQN_API T *Dqn_List_At(Dqn_List *list, Dqn_usize index, return result; } #endif // !defined(DQN_NO_LIST) - diff --git a/dqn_core.h b/dqn_core.h index e95cc6d..b12c8bc 100644 --- a/dqn_core.h +++ b/dqn_core.h @@ -234,11 +234,9 @@ int main() DQN_DEFER { printf("Three ..\n"); }; printf("One ..\n"); printf("Two ..\n"); - // One .. // Two .. // Three .. - return 0; } #endif @@ -278,16 +276,16 @@ typedef int32_t Dqn_b32; #define DQN_ISIZE_MIN INTPTR_MIN // NOTE [$GSTR] Global Structs ===================================================================== -struct Dqn_String8 ///< Pointer and length style UTF8 strings +struct Dqn_String8 { - char *data; ///< The UTF8 bytes of the string - Dqn_usize size; ///< The number of bytes in the string + char *data; // The bytes of the string + Dqn_usize size; // The number of bytes in the string #if defined(__cplusplus) - char const *begin() const { return data; } ///< Const begin iterator for range-for loops - char const *end () const { return data + size; } ///< Const end iterator for range-for loops - char *begin() { return data; } ///< Begin iterator for range-for loops - char *end () { return data + size; } ///< End iterator for range-for loops + char const *begin() const { return data; } // Const begin iterator for range-for loops + char const *end () const { return data + size; } // Const end iterator for range-for loops + char *begin() { return data; } // Begin iterator for range-for loops + char *end () { return data + size; } // End iterator for range-for loops #endif }; @@ -401,22 +399,22 @@ Dqn_CPUIDRegisters Dqn_CPUID(int function_id); // // @proc Dqn_TicketMutex_Begin, End // @desc Lock and unlock the mutex respectively -// + // @proc Dqn_TicketMutex_MakeTicket // @desc Allocate the next available ticket from the mutex for locking using // Dqn_TicketMutex_BeginTicket(). // @param[in] mutex The mutex -// @code -// Dqn_TicketMutex mutex = {}; -// unsigned int ticket = Dqn_TicketMutex_MakeTicket(&mutex); -// Dqn_TicketMutex_BeginTicket(&mutex, ticket); // Blocking call until we attain the lock -// Dqn_TicketMutex_End(&mutex); -// @endcode -// +#if 0 + Dqn_TicketMutex mutex = {}; + unsigned int ticket = Dqn_TicketMutex_MakeTicket(&mutex); + Dqn_TicketMutex_BeginTicket(&mutex, ticket); // Blocking call until we attain the lock + Dqn_TicketMutex_End(&mutex); +#endif + // @proc Dqn_TicketMutex_BeginTicket // @desc Lock the mutex using the given ticket if possible, otherwise block // waiting until the mutex can be locked. -// + // @proc Dqn_TicketMutex_CanLock // @desc Determine if the mutex can be locked using the given ticket number @@ -433,10 +431,10 @@ void Dqn_TicketMutex_BeginTicket(Dqn_TicketMutex const *mutex, Dqn_uint tick bool Dqn_TicketMutex_CanLock (Dqn_TicketMutex const *mutex, Dqn_uint ticket); // NOTE: [$CALL] Dqn_CallSite ====================================================================== -typedef struct Dqn_CallSite { +struct Dqn_CallSite +{ Dqn_String8 file; Dqn_String8 function; unsigned int line; -} Dqn_CalSite; - +}; #define DQN_CALL_SITE Dqn_CallSite{DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__} diff --git a/dqn_hash.h b/dqn_hash.h index 8ab607b..3cbd720 100644 --- a/dqn_hash.h +++ b/dqn_hash.h @@ -6,20 +6,22 @@ // ================================================================================================= // NOTE: [$FNV1] Dqn_FNV1A ========================================================================= -#ifndef DQN_FNV1A32_SEED +// NOTE: API ======================================================================================= +#if 0 + char buffer1[128] = {random bytes}; + char buffer2[128] = {random bytes}; + uint64_t hash = Dqn_FNV1A64_Hash(buffer1, sizeof(buffer1)); + hash = Dqn_FNV1A64_Iterate(buffer2, sizeof(buffer2), hash); // subsequent hashing +#endif + +#if !defined(DQN_FNV1A32_SEED) #define DQN_FNV1A32_SEED 2166136261U #endif -#ifndef DQN_FNV1A64_SEED +#if !defined(DQN_FNV1A64_SEED) #define DQN_FNV1A64_SEED 14695981039346656037ULL #endif -/// @begincode -/// char buffer1[128] = {random bytes}; -/// char buffer2[128] = {random bytes}; -/// uint64_t hash = Dqn_FNV1A64_Hash(buffer1, sizeof(buffer1)); -/// hash = Dqn_FNV1A64_Iterate(buffer2, sizeof(buffer2), hash); // subsequent hashing -/// @endcode DQN_API uint32_t Dqn_FNV1A32_Hash (void const *bytes, Dqn_usize size); DQN_API uint64_t Dqn_FNV1A64_Hash (void const *bytes, Dqn_usize size); DQN_API uint32_t Dqn_FNV1A32_Iterate(void const *bytes, Dqn_usize size, uint32_t hash); diff --git a/dqn_math.cpp b/dqn_math.cpp index e089d6f..51dd0a9 100644 --- a/dqn_math.cpp +++ b/dqn_math.cpp @@ -1,5 +1,5 @@ -#if !defined(DQN_NO_MATH) -// NOTE: [$MATH] Math ============================================================================== +#if !defined(DQN_NO_V2) +// NOTE: [$VEC2] Vector2 =========================================================================== DQN_API Dqn_V2I Dqn_V2ToV2I(Dqn_V2 a) { Dqn_V2I result = Dqn_V2I(DQN_CAST(int32_t)a.x, DQN_CAST(int32_t)a.y); @@ -51,9 +51,10 @@ DQN_API Dqn_V2 Dqn_V2Perpendicular(Dqn_V2 a) Dqn_V2 result = Dqn_V2(-a.y, a.x); return result; } +#endif // !defined(DQN_NO_V2) -// NOTE: Dqn_V3 Implementation -// ------------------------------------------------------------------------------------------------- +#if !defined(DQN_NO_V3) +// NOTE: [$VEC3] Vector3 =========================================================================== DQN_API Dqn_f32 Dqn_V3LengthSq(Dqn_V3 a) { Dqn_f32 result = DQN_SQUARED(a.x) + DQN_SQUARED(a.y) + DQN_SQUARED(a.z); @@ -73,17 +74,19 @@ DQN_API Dqn_V3 Dqn_V3Normalise(Dqn_V3 a) Dqn_V3 result = a / length; return result; } +#endif // !defined(DQN_NO_V3) -// NOTE: Dqn_V4 Implementation -// ------------------------------------------------------------------------------------------------- +#if !defined(DQN_NO_V4) +// NOTE: [$VEC4] Vector4 =========================================================================== DQN_API Dqn_f32 Dqn_V4Dot(Dqn_V4 a, Dqn_V4 b) { Dqn_f32 result = (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w); return result; } +#endif // !defined(DQN_NO_V4) -// NOTE: Dqn_M4 Implementation -// ------------------------------------------------------------------------------------------------- +#if !defined(DQN_NO_M4) +// NOTE: [$MAT4] Dqn_M4 ============================================================================ DQN_API Dqn_M4 Dqn_M4_Identity() { Dqn_M4 result = @@ -331,9 +334,10 @@ DQN_API Dqn_FString8<256> Dqn_M4_ColumnMajorString(Dqn_M4 mat) return result; } #endif +#endif // !defined(DQN_M4) -// NOTE: Dqn_Rect -// ------------------------------------------------------------------------------------------------- +#if !defined(DQN_NO_RECT) +// NOTE: [$RECT] Dqn_Rect ========================================================================== DQN_API Dqn_Rect Dqn_Rect_InitFromPosAndSize(Dqn_V2 pos, Dqn_V2 size) { Dqn_Rect result = {}; @@ -428,9 +432,9 @@ DQN_API Dqn_V2I Dqn_RectI32_Size(Dqn_RectI32 rect) Dqn_V2I result = rect.max - rect.min; return result; } +#endif // !defined(DQN_NO_RECT) -// NOTE: Math Utils -// ------------------------------------------------------------------------------------------------- +// NOTE: [$MATH] Other ============================================================================= DQN_API Dqn_V2 Dqn_Lerp_V2(Dqn_V2 a, Dqn_f32 t, Dqn_V2 b) { Dqn_V2 result = {}; @@ -444,5 +448,3 @@ DQN_API Dqn_f32 Dqn_Lerp_F32(Dqn_f32 a, Dqn_f32 t, Dqn_f32 b) Dqn_f32 result = a + ((b - a) * t); return result; } -#endif // !defined(DQN_NO_MATH) - diff --git a/dqn_math.h b/dqn_math.h index 422c9d7..e37bdf6 100644 --- a/dqn_math.h +++ b/dqn_math.h @@ -1,11 +1,16 @@ // NOTE: Table Of Contents ========================================================================= // Index | Disable #define | Description // ================================================================================================= -// [$MATH] Math | DQN_NO_MATH | v2i, V2, V3, V4, Mat4, Rect, RectI32, Lerp +// [$VEC2] Dqn_V2, V2i | DQN_NO_V2 | +// [$VEC3] Dqn_V3, V3i | DQN_NO_V3 | +// [$VEC4] Dqn_V4, V4i | DQN_NO_V4 | +// [$MAT4] Dqn_M4 | DQN_NO_M4 | +// [$RECT] Dqn_Rect | DQN_NO_RECT | +// [$MATH] Other | | // ================================================================================================= -#if !defined(DQN_NO_MATH) -// NOTE: [$MATH] Math ============================================================================== +#if !defined(DQN_NO_V2) +// NOTE: [$VEC2] Vector2 =========================================================================== struct Dqn_V2I { int32_t x, y; @@ -71,6 +76,18 @@ struct Dqn_V2 Dqn_V2 &operator+=(Dqn_V2 other) { *this = *this + other; return *this; } }; +DQN_API Dqn_V2I Dqn_V2ToV2I(Dqn_V2 a); +DQN_API Dqn_V2 Dqn_V2Min(Dqn_V2 a, Dqn_V2 b); +DQN_API Dqn_V2 Dqn_V2Max(Dqn_V2 a, Dqn_V2 b); +DQN_API Dqn_V2 Dqn_V2Abs(Dqn_V2 a); +DQN_API Dqn_f32 Dqn_V2Dot(Dqn_V2 a, Dqn_V2 b); +DQN_API Dqn_f32 Dqn_V2LengthSq(Dqn_V2 a, Dqn_V2 b); +DQN_API Dqn_V2 Dqn_V2Normalise(Dqn_V2 a); +DQN_API Dqn_V2 Dqn_V2Perpendicular(Dqn_V2 a); +#endif // !defined(DQN_NO_V2) + +#if !defined(DQN_NO_V3) +// NOTE: [$VEC3] Vector3 =========================================================================== struct Dqn_V3 { Dqn_f32 x, y, z; @@ -106,6 +123,18 @@ struct Dqn_V3 Dqn_V3 &operator+=(Dqn_V3 other) { *this = *this + other; return *this; } }; +DQN_API Dqn_f32 Dqn_V3LengthSq(Dqn_V3 a); +DQN_API Dqn_f32 Dqn_V3Length(Dqn_V3 a); +DQN_API Dqn_V3 Dqn_V3Normalise(Dqn_V3 a); +#endif // !defined(DQN_NO_V3) + +#if !defined(DQN_NO_V4) +// NOTE: [$VEC4] Vector4 =========================================================================== + +#if defined(DQN_NO_V3) + #error "Dqn_Rect requires Dqn_V3 hence DQN_NO_V3 must *not* be defined" +#endif + union Dqn_V4 { struct { Dqn_f32 x, y, z, w; }; @@ -139,26 +168,16 @@ union Dqn_V4 Dqn_V4 &operator-=(Dqn_V4 other) { *this = *this - other; return *this; } Dqn_V4 &operator+=(Dqn_V4 other) { *this = *this + other; return *this; } }; +#endif // !defined(DQN_NO_V4) +#if !defined(DQN_NO_M4) +// NOTE: [$MAT4] Dqn_M4 ============================================================================ // NOTE: Column major matrix struct Dqn_M4 { Dqn_f32 columns[4][4]; }; -DQN_API Dqn_V2I Dqn_V2ToV2I(Dqn_V2 a); -DQN_API Dqn_V2 Dqn_V2Min(Dqn_V2 a, Dqn_V2 b); -DQN_API Dqn_V2 Dqn_V2Max(Dqn_V2 a, Dqn_V2 b); -DQN_API Dqn_V2 Dqn_V2Abs(Dqn_V2 a); -DQN_API Dqn_f32 Dqn_V2Dot(Dqn_V2 a, Dqn_V2 b); -DQN_API Dqn_f32 Dqn_V2LengthSq(Dqn_V2 a, Dqn_V2 b); -DQN_API Dqn_V2 Dqn_V2Normalise(Dqn_V2 a); -DQN_API Dqn_V2 Dqn_V2Perpendicular(Dqn_V2 a); - -DQN_API Dqn_f32 Dqn_V3LengthSq(Dqn_V3 a); -DQN_API Dqn_f32 Dqn_V3Length(Dqn_V3 a); -DQN_API Dqn_V3 Dqn_V3Normalise(Dqn_V3 a); - DQN_API Dqn_f32 Dqn_V4Dot(Dqn_V4 a, Dqn_V4 b); DQN_API Dqn_M4 Dqn_M4_Identity(); @@ -182,6 +201,13 @@ DQN_API Dqn_M4 Dqn_M4_DivF(Dqn_M4 lhs, Dqn_f32 rhs); #if !defined(DQN_NO_FSTRING8) DQN_API Dqn_FString8<256> Dqn_M4_ColumnMajorString(Dqn_M4 mat); #endif +#endif // !defined(DQN_M4) + +// NOTE: [$RECT] Dqn_Rect ========================================================================== +#if !defined(DQN_NO_RECT) +#if defined(DQN_NO_V2) + #error "Dqn_Rect requires Dqn_V2 hence DQN_NO_V2 must *not* be defined" +#endif struct Dqn_Rect { @@ -212,8 +238,9 @@ DQN_API Dqn_Rect Dqn_Rect_Intersection(Dqn_Rect a, Dqn_Rect b); DQN_API Dqn_Rect Dqn_Rect_Union(Dqn_Rect a, Dqn_Rect b); DQN_API Dqn_Rect Dqn_Rect_FromRectI32(Dqn_RectI32 a); DQN_API Dqn_V2I Dqn_RectI32_Size(Dqn_RectI32 rect); +#endif // !defined(DQN_NO_RECT) +// NOTE: [$MATH] Other ============================================================================= DQN_API Dqn_V2 Dqn_Lerp_V2(Dqn_V2 a, Dqn_f32 t, Dqn_V2 b); DQN_API Dqn_f32 Dqn_Lerp_F32(Dqn_f32 a, Dqn_f32 t, Dqn_f32 b); -#endif // !defined(DQN_NO_MATH) diff --git a/dqn_memory.h b/dqn_memory.h index 0a34cc0..fd589f2 100644 --- a/dqn_memory.h +++ b/dqn_memory.h @@ -29,54 +29,36 @@ #define DQN_LEAK_TRACE_UNUSED #endif -typedef struct Dqn_LeakTrace { - void *ptr; ///< The pointer we are tracking - Dqn_usize size; ///< Size of the allocation - Dqn_CallSite call_site; ///< Call site where the allocation was allocated - bool freed; ///< True if this pointer has been freed - Dqn_usize freed_size; ///< Size of the allocation that has been freed - Dqn_CallSite freed_call_site; ///< Call site where the allocation was freed -} Dqn_LeakTrace; +struct Dqn_LeakTrace +{ + void *ptr; // The pointer we are tracking + Dqn_usize size; // Size of the allocation + Dqn_CallSite call_site; // Call site where the allocation was allocated + bool freed; // True if this pointer has been freed + Dqn_usize freed_size; // Size of the allocation that has been freed + Dqn_CallSite freed_call_site; // Call site where the allocation was freed +}; -/// Allocate memory -/// @param size The number of bytes to allocate -/// @param zero_mem Flag to indicate if the allocated memory should be zero-ed out -/// @param user_context The user assigned pointer in the allocator typedef void *Dqn_Allocator_AllocProc(DQN_LEAK_TRACE_FUNCTION size_t size, uint8_t align, Dqn_ZeroMem zero_mem, void *user_context); +typedef void Dqn_Allocator_DeallocProc(DQN_LEAK_TRACE_FUNCTION void *ptr, size_t size, void *user_context); -/// Deallocate memory -/// @param ptr The pointer to deallocate memory for -/// @param size The number of bytes to deallocate -/// @param user_context The user assigned pointer in the allocator -typedef void Dqn_Allocator_DeallocProc(DQN_LEAK_TRACE_FUNCTION void *ptr, size_t size, void *user_context); +struct Dqn_Allocator +{ + void *user_context; // User assigned pointer that is passed into the allocator functions + Dqn_Allocator_AllocProc *alloc; // Memory allocating routine + Dqn_Allocator_DeallocProc *dealloc; // Memory deallocating routine +}; -typedef struct Dqn_Allocator { - void *user_context; ///< User assigned pointer that is passed into the allocator functions - Dqn_Allocator_AllocProc *alloc; ///< Memory allocating routine - Dqn_Allocator_DeallocProc *dealloc; ///< Memory deallocating routine -} Dqn_Allocator; - -/// Allocate bytes from the given allocator -/// @param[in] allocator The allocator to allocate bytes from -/// @param[in] size The amount of bytes to allocator -/// @param[in] zero_mem Flag to indicate if the allocated must be zero-ed out +// NOTE: Macros ================================================================================== #define Dqn_Allocator_Alloc(allocator, size, align, zero_mem) Dqn_Allocator_Alloc_(DQN_LEAK_TRACE allocator, size, align, zero_mem) -void *Dqn_Allocator_Alloc_(DQN_LEAK_TRACE_FUNCTION Dqn_Allocator allocator, size_t size, uint8_t align, Dqn_ZeroMem zero_mem); - -/// Deallocate the memory from the pointer using the allocator -/// -/// The pointer must originally have been allocated from the passed in -/// allocator. The size must also match the size that was originally allocated. -/// -/// @param[in] allocator The allocator to allocate bytes from -/// @param[in] ptr The pointer to deallocate -/// @param[in] size The amount of bytes to deallocate. #define Dqn_Allocator_Dealloc(allocator, ptr, size) Dqn_Allocator_Dealloc_(DQN_LEAK_TRACE allocator, ptr, size) -void Dqn_Allocator_Dealloc_(DQN_LEAK_TRACE_FUNCTION Dqn_Allocator allocator, void *ptr, size_t size); - #define Dqn_Allocator_NewArray(allocator, Type, count, zero_mem) (Type *)Dqn_Allocator_Alloc_(DQN_LEAK_TRACE allocator, sizeof(Type) * count, alignof(Type), zero_mem) #define Dqn_Allocator_New(allocator, Type, zero_mem) (Type *)Dqn_Allocator_Alloc_(DQN_LEAK_TRACE allocator, sizeof(Type), alignof(Type), zero_mem) +// NOTE: Internal ================================================================================== +void *Dqn_Allocator_Alloc_ (DQN_LEAK_TRACE_FUNCTION Dqn_Allocator allocator, size_t size, uint8_t align, Dqn_ZeroMem zero_mem); +void Dqn_Allocator_Dealloc_(DQN_LEAK_TRACE_FUNCTION Dqn_Allocator allocator, void *ptr, size_t size); + // NOTE: [$VMEM] Dqn_VMem ========================================================================== enum Dqn_VMemCommit { @@ -86,21 +68,23 @@ enum Dqn_VMemCommit enum Dqn_VMemPage { - /// Exception on read/write with a page. This flag overrides the read/write access. + // Exception on read/write with a page. This flag overrides the read/write + // access. Dqn_VMemPage_NoAccess = 1 << 0, - /// Only read permitted on the page. + // Only read permitted on the page. Dqn_VMemPage_Read = 1 << 1, - /// Only write permitted on the page. On Windows this is not supported and will be promoted to - /// read+write permissions. + // Only write permitted on the page. On Windows this is not supported and + // will be promoted to read+write permissions. Dqn_VMemPage_Write = 1 << 2, Dqn_VMemPage_ReadWrite = Dqn_VMemPage_Read | Dqn_VMemPage_Write, - /// Modifier used in conjunction with previous flags. Raises exception on first access to the - /// page, then, the underlying protection flags are active. This is supported on Windows, on - /// other OS's using this flag will set the OS equivalent of Dqn_VMemPage_NoAccess. + // Modifier used in conjunction with previous flags. Raises exception on + // first access to the page, then, the underlying protection flags are + // active. This is supported on Windows, on other OS's using this flag will + // set the OS equivalent of Dqn_VMemPage_NoAccess. Dqn_VMemPage_Guard = 1 << 3, }; @@ -149,7 +133,6 @@ DQN_API int Dqn_VMem_Protect (void *ptr, Dqn_usize size, uint32_t page_flags); // 64GB) since the arena only commits as much as needed. // // NOTE: API -// // @proc Dqn_Arena_Grow // @desc Grow the arena's capacity by allocating a block of memory with the // requested size. The requested size is rounded up to the nearest 64k @@ -160,7 +143,7 @@ DQN_API int Dqn_VMem_Protect (void *ptr, Dqn_usize size, uint32_t page_flags); // pages from the OS. // @param flags[in] Bit flags from 'Dqn_ArenaBlockFlags', set to 0 if none // @return The block of memory that -// + // @proc Dqn_Arena_Allocate, Dqn_Arena_New, Dqn_Arena_NewArray, // Dqn_Arena_NewArrayWithBlock, // @desc Allocate byte/objects @@ -169,37 +152,37 @@ DQN_API int Dqn_VMem_Protect (void *ptr, Dqn_usize size, uint32_t page_flags); // `NewArray` allocates an array of objects // `NewArrayWithBlock` allocates an array of objects from the given memory 'block' // @return A pointer to the allocated bytes/object. Null pointer on failure -// + // @proc Dqn_Arena_Copy, Dqn_Arena_CopyZ // @desc Allocate a copy of an object's bytes. The 'Z' variant adds // a null-terminating byte at the end of the stream. // @return A pointer to the allocated object. Null pointer on failure. -// + // @proc Dqn_Arena_Reset // @desc Set the arena's current block to the first block in the linked list // of blocks and mark all blocks free. // @param[in] zero_mem When yes, the memory is cleared using DQN_MEMSET with the // value of DQN_MEMSET_BYTE -// + // @proc Dqn_Arena_Free // @desc Free the arena returning all memory back to the OS // @param[in] zero_mem: When true, the memory is cleared using DQN_MEMSET with // the value of DQN_MEMSET_BYTE -// + // @proc Dqn_Arena_BeginTempMemory // @desc Begin an allocation scope where all allocations between begin and end // calls will be reverted. Useful for short-lived or highly defined lifetime // allocations. An allocation scope is invalidated if the arena is freed // between the begin and end call. -// + // @proc Dqn_Arena_EndTempMemory // @desc End an allocation scope previously begun by calling begin scope. -// + // @proc Dqn_Arena_StatString // @desc Dump the stats of the given arena to a string // @param[in] arena The arena to dump stats for // @return A stack allocated string containing the stats of the arena -// + // @proc Dqn_Arena_LogStats // @desc Dump the stats of the given arena to the memory log-stream. // @param[in] arena The arena to dump stats for @@ -211,29 +194,29 @@ enum Dqn_ArenaBlockFlags struct Dqn_ArenaStat { - Dqn_usize capacity; ///< Total allocating capacity of the arena in bytes - Dqn_usize used; ///< Total amount of bytes used in the arena - Dqn_usize wasted; ///< Orphaned space in blocks due to allocations requiring more space than available in the active block - uint32_t blocks; ///< Number of memory blocks in the arena - Dqn_usize syscalls; ///< Number of memory allocation syscalls into the OS + Dqn_usize capacity; // Total allocating capacity of the arena in bytes + Dqn_usize used; // Total amount of bytes used in the arena + Dqn_usize wasted; // Orphaned space in blocks due to allocations requiring more space than available in the active block + uint32_t blocks; // Number of memory blocks in the arena + Dqn_usize syscalls; // Number of memory allocation syscalls into the OS - Dqn_usize capacity_hwm; ///< High-water mark for 'capacity' - Dqn_usize used_hwm; ///< High-water mark for 'used' - Dqn_usize wasted_hwm; ///< High-water mark for 'wasted' - uint32_t blocks_hwm; ///< High-water mark for 'blocks' + Dqn_usize capacity_hwm; // High-water mark for 'capacity' + Dqn_usize used_hwm; // High-water mark for 'used' + Dqn_usize wasted_hwm; // High-water mark for 'wasted' + uint32_t blocks_hwm; // High-water mark for 'blocks' }; struct Dqn_ArenaBlock { - struct Dqn_Arena *arena; ///< Arena that owns this block - void *memory; ///< Backing memory of the block - Dqn_usize size; ///< Size of the block - Dqn_usize used; ///< Number of bytes used up in the block. Always less than the commit amount. - Dqn_usize hwm_used;///< High-water mark for 'used' bytes in this block - Dqn_usize commit; ///< Number of bytes in the block physically backed by pages - Dqn_ArenaBlock *prev; ///< Previous linked block - Dqn_ArenaBlock *next; ///< Next linked block - uint8_t flags; ///< Bit field for 'Dqn_ArenaBlockFlags' + struct Dqn_Arena *arena; // Arena that owns this block + void *memory; // Backing memory of the block + Dqn_usize size; // Size of the block + Dqn_usize used; // Number of bytes used up in the block. Always less than the commit amount. + Dqn_usize hwm_used;// High-water mark for 'used' bytes in this block + Dqn_usize commit; // Number of bytes in the block physically backed by pages + Dqn_ArenaBlock *prev; // Previous linked block + Dqn_ArenaBlock *next; // Next linked block + uint8_t flags; // Bit field for 'Dqn_ArenaBlockFlags' }; struct Dqn_ArenaStatString @@ -246,21 +229,21 @@ struct Dqn_Arena { bool use_after_free_guard; uint32_t temp_memory_count; - Dqn_String8 label; ///< Optional label to describe the arena - Dqn_ArenaBlock *head; ///< Active block the arena is allocating from - Dqn_ArenaBlock *curr; ///< Active block the arena is allocating from - Dqn_ArenaBlock *tail; ///< Last block in the linked list of blocks - Dqn_ArenaStat stats; ///< Current arena stats, reset when reset usage is invoked. + Dqn_String8 label; // Optional label to describe the arena + Dqn_ArenaBlock *head; // Active block the arena is allocating from + Dqn_ArenaBlock *curr; // Active block the arena is allocating from + Dqn_ArenaBlock *tail; // Last block in the linked list of blocks + Dqn_ArenaStat stats; // Current arena stats, reset when reset usage is invoked. }; struct Dqn_ArenaTempMemory { - Dqn_Arena *arena; ///< Arena the scope is for - Dqn_ArenaBlock *head; ///< Head block of the arena at the beginning of the scope - Dqn_ArenaBlock *curr; ///< Current block of the arena at the beginning of the scope - Dqn_ArenaBlock *tail; ///< Tail block of the arena at the beginning of the scope - Dqn_usize curr_used; ///< Current used amount of the current block - Dqn_ArenaStat stats; ///< Stats of the arena at the beginning of the scope + Dqn_Arena *arena; // Arena the scope is for + Dqn_ArenaBlock *head; // Head block of the arena at the beginning of the scope + Dqn_ArenaBlock *curr; // Current block of the arena at the beginning of the scope + Dqn_ArenaBlock *tail; // Tail block of the arena at the beginning of the scope + Dqn_usize curr_used; // Current used amount of the current block + Dqn_ArenaStat stats; // Stats of the arena at the beginning of the scope }; // Automatically begin and end a temporary memory scope on object construction @@ -279,10 +262,10 @@ struct Dqn_ArenaTempMemoryScope_ enum Dqn_ArenaCommit { - /// Commit the pages to ensure the block has the requested commit amount. - /// No-op if the block has sufficient commit space already. + // Commit the pages to ensure the block has the requested commit amount. + // No-op if the block has sufficient commit space already. Dqn_ArenaCommit_EnsureSpace, - Dqn_ArenaCommit_GetNewPages, ///< Grow the block by the requested commit amount + Dqn_ArenaCommit_GetNewPages, // Grow the block by the requested commit amount }; // NOTE: Allocation ================================================================================ @@ -326,7 +309,7 @@ struct Dqn_ArenaCatalogItem struct Dqn_ArenaCatalog { - Dqn_TicketMutex ticket_mutex; ///< Mutex for adding to the linked list of arenas + Dqn_TicketMutex ticket_mutex; // Mutex for adding to the linked list of arenas Dqn_Arena *arena; Dqn_ArenaCatalogItem sentinel; uint16_t arena_count;