dqn: Cleanup more documentation

This commit is contained in:
doyle 2023-07-06 21:13:52 +10:00
parent 55dbc25110
commit 2bbc49242e
6 changed files with 227 additions and 208 deletions

View File

@ -28,24 +28,26 @@
// //
// In addition to no realloc on expansion or shrinking. // 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 // @proc Dqn_VArray_InitByteSize, Dqn_VArray_Init
// @desc Initialise an array with the requested byte size or item capacity // @desc Initialise an array with the requested byte size or item capacity
// respectively. The returned array may have a higher capacity than the // respectively. The returned array may have a higher capacity than the
// requested amount since requested memory from the OS may have a certain // requested amount since requested memory from the OS may have a certain
// alignment requirement (e.g. on Windows reserve/commit are 64k/4k aligned). // alignment requirement (e.g. on Windows reserve/commit are 64k/4k aligned).
//
// @proc Dqn_VArray_IsValid // @proc Dqn_VArray_IsValid
// @desc Verify if the array has been initialised // @desc Verify if the array has been initialised
//
// @proc Dqn_VArray_Make, Dqn_VArray_Add // @proc Dqn_VArray_Make, Dqn_VArray_Add
// @desc Allocate items into the array // @desc Allocate items into the array
// 'Make' creates the `count` number of requested items // 'Make' creates the `count` number of requested items
// 'Add' adds the array of items into the array // 'Add' adds the array of items into the array
// @return The array of items allocated. Null pointer if the array is invalid // @return The array of items allocated. Null pointer if the array is invalid
// or the array has insufficient space for the requested items. // or the array has insufficient space for the requested items.
//
// @proc Dqn_VArray_EraseRange // @proc Dqn_VArray_EraseRange
// @desc Erase the next `count` items at `begin_index` in the array. `count` // @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 // 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 // @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 // the erase ranged into the range. Unstable erase will copy the tail elements
// into the range to delete. // into the range to delete.
//
// @proc Dqn_VArray_Clear // @proc Dqn_VArray_Clear
// @desc Set the size of the array to 0 // @desc Set the size of the array to 0
//
// @proc Dqn_VArray_Reserve // @proc Dqn_VArray_Reserve
// @desc Ensure that the requested number of items are backed by physical // @desc Ensure that the requested number of items are backed by physical
// pages from the OS. Calling this pre-emptively will minimise syscalls into // 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 // 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 // reserved space may be greater than the requested amount (e.g. this is 4k
// on Windows). // on Windows).
//
// TODO(doyle)
//
// Add an API for shrinking the array by decomitting pages back to the OS.
template <typename T> struct Dqn_VArray template <typename T> struct Dqn_VArray
{ {
Dqn_ArenaBlock *block; ///< Block of memory from the allocator for this array 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 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 size; // Number of items currently in the array
Dqn_usize max; ///< Maximum number of items this array can store Dqn_usize max; // Maximum number of items this array can store
T *begin() { return data; } T *begin() { return data; }
T *end () { return data + size; } T *end () { return data + size; }
@ -91,14 +89,19 @@ enum Dqn_VArrayErase
Dqn_VArrayErase_Stable, Dqn_VArrayErase_Stable,
}; };
// NOTE: Setup =====================================================================================
DQN_API template <typename T> Dqn_VArray<T> Dqn_VArray_InitByteSize(Dqn_Arena *arena, Dqn_usize byte_size); DQN_API template <typename T> Dqn_VArray<T> Dqn_VArray_InitByteSize(Dqn_Arena *arena, Dqn_usize byte_size);
DQN_API template <typename T> Dqn_VArray<T> Dqn_VArray_Init (Dqn_Arena *arena, Dqn_usize max); DQN_API template <typename T> Dqn_VArray<T> Dqn_VArray_Init (Dqn_Arena *arena, Dqn_usize max);
DQN_API template <typename T> bool Dqn_VArray_IsValid (Dqn_VArray<T> const *array); DQN_API template <typename T> bool Dqn_VArray_IsValid (Dqn_VArray<T> const *array);
DQN_API template <typename T> void Dqn_VArray_Reserve (Dqn_VArray<T> *array, Dqn_usize count);
// NOTE: Insert ====================================================================================
DQN_API template <typename T> T * Dqn_VArray_Make (Dqn_VArray<T> *array, Dqn_usize count, Dqn_ZeroMem zero_mem); DQN_API template <typename T> T * Dqn_VArray_Make (Dqn_VArray<T> *array, Dqn_usize count, Dqn_ZeroMem zero_mem);
DQN_API template <typename T> T * Dqn_VArray_Add (Dqn_VArray<T> *array, T const *items, Dqn_usize count); DQN_API template <typename T> T * Dqn_VArray_Add (Dqn_VArray<T> *array, T const *items, Dqn_usize count);
// NOTE: Modify ====================================================================================
DQN_API template <typename T> void Dqn_VArray_EraseRange (Dqn_VArray<T> *array, Dqn_usize begin_index, Dqn_isize count, Dqn_VArrayErase erase); DQN_API template <typename T> void Dqn_VArray_EraseRange (Dqn_VArray<T> *array, Dqn_usize begin_index, Dqn_isize count, Dqn_VArrayErase erase);
DQN_API template <typename T> void Dqn_VArray_Clear (Dqn_VArray<T> *array); DQN_API template <typename T> void Dqn_VArray_Clear (Dqn_VArray<T> *array);
DQN_API template <typename T> void Dqn_VArray_Reserve (Dqn_VArray<T> *array, Dqn_usize count);
#endif // !defined(DQN_NO_VARRAY) #endif // !defined(DQN_NO_VARRAY)
#if !defined(DQN_NO_DSMAP) #if !defined(DQN_NO_DSMAP)
@ -149,27 +152,27 @@ DQN_API template <typename T> void Dqn_VArray_Reserve (Dqn_VArray<
// //
// - Functions that return a pointer or boolean will always return null or false // - 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. // if the passed in map is invalid e.g. `DSMap_IsValid()` returns false.
//
// @proc Dqn_DSMap_Init // @proc Dqn_DSMap_Init
// @param size[in] The number of slots in the table. This size must be a // @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. // power-of-two or otherwise an assert will be triggered.
// @return The hash table. On memory allocation failure, the table will be // @return The hash table. On memory allocation failure, the table will be
// zero initialised whereby calling Dqn_DSMap_IsValid() will return false. // zero initialised whereby calling Dqn_DSMap_IsValid() will return false.
//
// @proc Dqn_DSMap_Deinit // @proc Dqn_DSMap_Deinit
// @desc Free the memory allocated by the table // @desc Free the memory allocated by the table
//
// @proc Dqn_DSMap_IsValid // @proc Dqn_DSMap_IsValid
// @desc Verify that the table is in a valid state (e.g. initialised // @desc Verify that the table is in a valid state (e.g. initialised
// correctly). // correctly).
//
// @proc Dqn_DSMap_Hash // @proc Dqn_DSMap_Hash
// @desc Hash the input key using the custom hash function if it's set on the // @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). // map, otherwise uses the default hashing function (32bit Murmur3).
// //
// @proc Dqn_DSMap_HashToSlotIndex // @proc Dqn_DSMap_HashToSlotIndex
// @desc Calculate the index into the map's `slots` array from the given hash. // @desc Calculate the index into the map's `slots` array from the given hash.
//
// @proc Dqn_DSMap_FindSlot, Dqn_DSMap_Find // @proc Dqn_DSMap_FindSlot, Dqn_DSMap_Find
// @desc Find the slot in the map's `slots` array corresponding to the given // @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 // key and hash. If the map does not contain the key, a null pointer is
@ -177,7 +180,7 @@ DQN_API template <typename T> void Dqn_VArray_Reserve (Dqn_VArray<
// //
// `Find` returns the value. // `Find` returns the value.
// `FindSlot` returns the map's hash table slot. // `FindSlot` returns the map's hash table slot.
//
// @proc Dqn_DSMap_MakeSlot, Dqn_DSMap_Make, Dqn_DSMap_Set, Dqn_DSMap_SetSlot // @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, // @desc Same as `DSMap_Find*` except if the key does not exist in the table,
// a hash-table slot will be made. // a hash-table slot will be made.
@ -194,20 +197,20 @@ DQN_API template <typename T> void Dqn_VArray_Reserve (Dqn_VArray<
// @param found[out] Pass a pointer to a bool. The bool will be set to true // @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 // if the item already existed in the map before, or false if the item was
// just created by this call. // just created by this call.
//
// @proc Dqn_DSMap_Resize // @proc Dqn_DSMap_Resize
// @desc Resize the table and move all elements to the new map. // @desc Resize the table and move all elements to the new map.
// the elements currently set in the // the elements currently set in the
// @param size[in] New size of the table, must be a power of two. // @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 // @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. // than the current number of elements in the map to resize. True otherwise.
//
// @proc Dqn_DSMap_Erase // @proc Dqn_DSMap_Erase
// @desc Remove the key-value pair from the table. If by erasing the key-value // @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 // 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 // by 1/2 the current size after erasing. The table will not shrink below the
// initial size that the table was initialised as. // initial size that the table was initialised as.
//
// @proc Dqn_DSMap_KeyCStringLit, Dqn_DSMap_KeyU64, Dqn_DSMap_KeyBuffer, // @proc Dqn_DSMap_KeyCStringLit, Dqn_DSMap_KeyU64, Dqn_DSMap_KeyBuffer,
// Dqn_DSMap_KeyString8 Dqn_DSMap_KeyString8Copy // Dqn_DSMap_KeyString8 Dqn_DSMap_KeyString8Copy
// @desc Create a hash-table key given // @desc Create a hash-table key given
@ -221,7 +224,7 @@ DQN_API template <typename T> void Dqn_VArray_Reserve (Dqn_VArray<
// If the key points to an array of bytes, the lifetime of those bytes *must* // 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 // remain valid throughout the lifetime of the map as the pointers are value
// copied into the hash table! // copied into the hash table!
//
// @proc Dqn_DSMap_KeyU64NoHash // @proc Dqn_DSMap_KeyU64NoHash
// @desc Create a hash-table key given the uint64. This u64 is *not* hashed to // @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 // map values into the table. This is useful if you already have a source of
@ -234,9 +237,9 @@ DQN_API template <typename T> void Dqn_VArray_Reserve (Dqn_VArray<
enum Dqn_DSMapKeyType enum Dqn_DSMapKeyType
{ {
Dqn_DSMapKeyType_Invalid, Dqn_DSMapKeyType_Invalid,
Dqn_DSMapKeyType_U64, ///< Use a U64 key that is `hash(u64) % 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_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_Buffer, // Use a buffer key that is `hash(buffer) % size` to map into the table
}; };
struct Dqn_DSMapKey struct Dqn_DSMapKey
@ -261,14 +264,14 @@ template <typename T> struct Dqn_DSMapSlot
using Dqn_DSMapHashFunction = uint32_t(Dqn_DSMapKey key, uint32_t seed); using Dqn_DSMapHashFunction = uint32_t(Dqn_DSMapKey key, uint32_t seed);
template <typename T> struct Dqn_DSMap template <typename T> struct Dqn_DSMap
{ {
uint32_t *hash_to_slot; ///< Mapping from hash to a index in the slots array uint32_t *hash_to_slot; // Mapping from hash to a index in the slots array
Dqn_DSMapSlot<T> *slots; ///< Values of the array stored contiguously, non-sorted order Dqn_DSMapSlot<T> *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 size; // Total capacity of the map and is a power of two
uint32_t occupied; ///< Number of slots used in the hash table uint32_t occupied; // Number of slots used in the hash table
Dqn_Allocator allocator; ///< Backing allocator for 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 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 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_seed; // Seed for the hashing function, when 0, DQN_DS_MAP_DEFAULT_HASH_SEED is used
}; };
// NOTE: Setup ===================================================================================== // NOTE: Setup =====================================================================================
@ -305,8 +308,8 @@ DQN_API bool operator== (Dqn_DS
// NOTE: [$FARR] Dqn_FArray ======================================================================== // NOTE: [$FARR] Dqn_FArray ========================================================================
template <typename T, Dqn_usize N> struct Dqn_FArray template <typename T, Dqn_usize N> struct Dqn_FArray
{ {
T data[N]; ///< Pointer to the start of the array items in the block of memory 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 Dqn_usize size; // Number of items currently in the array
T *begin() { return data; } T *begin() { return data; }
T *end () { return data + size; } T *end () { return data + size; }
@ -320,35 +323,40 @@ enum Dqn_FArrayErase
Dqn_FArrayErase_Stable, Dqn_FArrayErase_Stable,
}; };
// NOTE: Setup =====================================================================================
DQN_API template <typename T, Dqn_usize N> Dqn_FArray<T, N> Dqn_FArray_Init (T const *array, Dqn_usize count); DQN_API template <typename T, Dqn_usize N> Dqn_FArray<T, N> Dqn_FArray_Init (T const *array, Dqn_usize count);
DQN_API template <typename T, Dqn_usize N> bool Dqn_FArray_IsValid (Dqn_FArray<T, N> const *array); DQN_API template <typename T, Dqn_usize N> bool Dqn_FArray_IsValid (Dqn_FArray<T, N> const *array);
// NOTE: Insert ====================================================================================
DQN_API template <typename T, Dqn_usize N> T * Dqn_FArray_Make (Dqn_FArray<T, N> *array, Dqn_usize count, Dqn_ZeroMem zero_mem); DQN_API template <typename T, Dqn_usize N> T * Dqn_FArray_Make (Dqn_FArray<T, N> *array, Dqn_usize count, Dqn_ZeroMem zero_mem);
DQN_API template <typename T, Dqn_usize N> T * Dqn_FArray_Add (Dqn_FArray<T, N> *array, T const *items, Dqn_usize count); DQN_API template <typename T, Dqn_usize N> T * Dqn_FArray_Add (Dqn_FArray<T, N> *array, T const *items, Dqn_usize count);
// NOTE: Modify ====================================================================================
DQN_API template <typename T, Dqn_usize N> void Dqn_FArray_EraseRange(Dqn_FArray<T, N> *array, Dqn_usize begin_index, Dqn_isize count, Dqn_FArrayErase erase); DQN_API template <typename T, Dqn_usize N> void Dqn_FArray_EraseRange(Dqn_FArray<T, N> *array, Dqn_usize begin_index, Dqn_isize count, Dqn_FArrayErase erase);
DQN_API template <typename T, Dqn_usize N> void Dqn_FArray_Clear (Dqn_FArray<T, N> *array); DQN_API template <typename T, Dqn_usize N> void Dqn_FArray_Clear (Dqn_FArray<T, N> *array);
#endif // !defined(DQN_NO_FARRAY) #endif // !defined(DQN_NO_FARRAY)
#if !defined(DQN_NO_LIST) #if !defined(DQN_NO_LIST)
// NOTE: [$LIST] Dqn_List ========================================================================== // NOTE: [$LIST] Dqn_List ==========================================================================
// NOTE: API
// //
// NOTE: API
// @proc Dqn_List_At // @proc Dqn_List_At
// @param at_chunk[out] (Optional) The chunk that the index belongs to will // @param at_chunk[out] (Optional) The chunk that the index belongs to will
// be set in this parameter if given // be set in this parameter if given
// @return The element, or null pointer if it is not a valid index. // @return The element, or null pointer if it is not a valid index.
//
// @proc Dqn_List_Iterate // @proc Dqn_List_Iterate
// @desc Produce an iterator for the data in the list // @desc Produce an iterator for the data in the list
// //
// @param[in] start_index The index to start iterating from // @param[in] start_index The index to start iterating from
// //
// @begincode #if 0
// Dqn_List<int> list = {}; Dqn_List<int> list = {};
// for (Dqn_ListIterator<int> it = {}; Dqn_List_Iterate(&list, &it, 0);) for (Dqn_ListIterator<int> it = {}; Dqn_List_Iterate(&list, &it, 0);)
// { {
// int *item = it.data; int *item = it.data;
// } }
// @endcode #endif
template <typename T> struct Dqn_ListChunk template <typename T> struct Dqn_ListChunk
{ {
@ -361,10 +369,10 @@ template <typename T> struct Dqn_ListChunk
template <typename T> struct Dqn_ListIterator template <typename T> struct Dqn_ListIterator
{ {
Dqn_b32 init; // (Internal): True if Dqn_List_Iterate has been called at-least once on this iterator Dqn_b32 init; // True if Dqn_List_Iterate has been called at-least once on this iterator
Dqn_ListChunk<T> *chunk; // (Internal): The chunk that the iterator is reading from Dqn_ListChunk<T> *chunk; // The chunk that the iterator is reading from
Dqn_usize chunk_data_index; // (Internal): The index in the chunk the iterator is referencing Dqn_usize chunk_data_index; // The index in the chunk the iterator is referencing
T *data; // (Read): Pointer to the data the iterator is referencing. Nullptr if invalid. T *data; // Pointer to the data the iterator is referencing. Nullptr if invalid.
}; };
template <typename T> struct Dqn_List template <typename T> struct Dqn_List
@ -1064,4 +1072,3 @@ template <typename T> DQN_API T *Dqn_List_At(Dqn_List<T> *list, Dqn_usize index,
return result; return result;
} }
#endif // !defined(DQN_NO_LIST) #endif // !defined(DQN_NO_LIST)

View File

@ -234,11 +234,9 @@ int main()
DQN_DEFER { printf("Three ..\n"); }; DQN_DEFER { printf("Three ..\n"); };
printf("One ..\n"); printf("One ..\n");
printf("Two ..\n"); printf("Two ..\n");
// One .. // One ..
// Two .. // Two ..
// Three .. // Three ..
return 0; return 0;
} }
#endif #endif
@ -278,16 +276,16 @@ typedef int32_t Dqn_b32;
#define DQN_ISIZE_MIN INTPTR_MIN #define DQN_ISIZE_MIN INTPTR_MIN
// NOTE [$GSTR] Global Structs ===================================================================== // NOTE [$GSTR] Global Structs =====================================================================
struct Dqn_String8 ///< Pointer and length style UTF8 strings struct Dqn_String8
{ {
char *data; ///< The UTF8 bytes of the string char *data; // The bytes of the string
Dqn_usize size; ///< The number of bytes in the string Dqn_usize size; // The number of bytes in the string
#if defined(__cplusplus) #if defined(__cplusplus)
char const *begin() const { return data; } ///< Const begin 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 const *end () const { return data + size; } // Const end iterator for range-for loops
char *begin() { return data; } ///< Begin 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 *end () { return data + size; } // End iterator for range-for loops
#endif #endif
}; };
@ -401,22 +399,22 @@ Dqn_CPUIDRegisters Dqn_CPUID(int function_id);
// //
// @proc Dqn_TicketMutex_Begin, End // @proc Dqn_TicketMutex_Begin, End
// @desc Lock and unlock the mutex respectively // @desc Lock and unlock the mutex respectively
//
// @proc Dqn_TicketMutex_MakeTicket // @proc Dqn_TicketMutex_MakeTicket
// @desc Allocate the next available ticket from the mutex for locking using // @desc Allocate the next available ticket from the mutex for locking using
// Dqn_TicketMutex_BeginTicket(). // Dqn_TicketMutex_BeginTicket().
// @param[in] mutex The mutex // @param[in] mutex The mutex
// @code #if 0
// Dqn_TicketMutex mutex = {}; Dqn_TicketMutex mutex = {};
// unsigned int ticket = Dqn_TicketMutex_MakeTicket(&mutex); unsigned int ticket = Dqn_TicketMutex_MakeTicket(&mutex);
// Dqn_TicketMutex_BeginTicket(&mutex, ticket); // Blocking call until we attain the lock Dqn_TicketMutex_BeginTicket(&mutex, ticket); // Blocking call until we attain the lock
// Dqn_TicketMutex_End(&mutex); Dqn_TicketMutex_End(&mutex);
// @endcode #endif
//
// @proc Dqn_TicketMutex_BeginTicket // @proc Dqn_TicketMutex_BeginTicket
// @desc Lock the mutex using the given ticket if possible, otherwise block // @desc Lock the mutex using the given ticket if possible, otherwise block
// waiting until the mutex can be locked. // waiting until the mutex can be locked.
//
// @proc Dqn_TicketMutex_CanLock // @proc Dqn_TicketMutex_CanLock
// @desc Determine if the mutex can be locked using the given ticket number // @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); bool Dqn_TicketMutex_CanLock (Dqn_TicketMutex const *mutex, Dqn_uint ticket);
// NOTE: [$CALL] Dqn_CallSite ====================================================================== // NOTE: [$CALL] Dqn_CallSite ======================================================================
typedef struct Dqn_CallSite { struct Dqn_CallSite
{
Dqn_String8 file; Dqn_String8 file;
Dqn_String8 function; Dqn_String8 function;
unsigned int line; unsigned int line;
} Dqn_CalSite; };
#define DQN_CALL_SITE Dqn_CallSite{DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__} #define DQN_CALL_SITE Dqn_CallSite{DQN_STRING8(__FILE__), DQN_STRING8(__func__), __LINE__}

View File

@ -6,20 +6,22 @@
// ================================================================================================= // =================================================================================================
// NOTE: [$FNV1] Dqn_FNV1A ========================================================================= // 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 #define DQN_FNV1A32_SEED 2166136261U
#endif #endif
#ifndef DQN_FNV1A64_SEED #if !defined(DQN_FNV1A64_SEED)
#define DQN_FNV1A64_SEED 14695981039346656037ULL #define DQN_FNV1A64_SEED 14695981039346656037ULL
#endif #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 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 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); DQN_API uint32_t Dqn_FNV1A32_Iterate(void const *bytes, Dqn_usize size, uint32_t hash);

View File

@ -1,5 +1,5 @@
#if !defined(DQN_NO_MATH) #if !defined(DQN_NO_V2)
// NOTE: [$MATH] Math ============================================================================== // NOTE: [$VEC2] Vector2 ===========================================================================
DQN_API Dqn_V2I Dqn_V2ToV2I(Dqn_V2 a) 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); 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); Dqn_V2 result = Dqn_V2(-a.y, a.x);
return result; 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_API Dqn_f32 Dqn_V3LengthSq(Dqn_V3 a)
{ {
Dqn_f32 result = DQN_SQUARED(a.x) + DQN_SQUARED(a.y) + DQN_SQUARED(a.z); 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; Dqn_V3 result = a / length;
return result; 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_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); Dqn_f32 result = (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w);
return result; 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_API Dqn_M4 Dqn_M4_Identity()
{ {
Dqn_M4 result = Dqn_M4 result =
@ -331,9 +334,10 @@ DQN_API Dqn_FString8<256> Dqn_M4_ColumnMajorString(Dqn_M4 mat)
return result; return result;
} }
#endif #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_API Dqn_Rect Dqn_Rect_InitFromPosAndSize(Dqn_V2 pos, Dqn_V2 size)
{ {
Dqn_Rect result = {}; Dqn_Rect result = {};
@ -428,9 +432,9 @@ DQN_API Dqn_V2I Dqn_RectI32_Size(Dqn_RectI32 rect)
Dqn_V2I result = rect.max - rect.min; Dqn_V2I result = rect.max - rect.min;
return result; 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_API Dqn_V2 Dqn_Lerp_V2(Dqn_V2 a, Dqn_f32 t, Dqn_V2 b)
{ {
Dqn_V2 result = {}; 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); Dqn_f32 result = a + ((b - a) * t);
return result; return result;
} }
#endif // !defined(DQN_NO_MATH)

View File

@ -1,11 +1,16 @@
// NOTE: Table Of Contents ========================================================================= // NOTE: Table Of Contents =========================================================================
// Index | Disable #define | Description // 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) #if !defined(DQN_NO_V2)
// NOTE: [$MATH] Math ============================================================================== // NOTE: [$VEC2] Vector2 ===========================================================================
struct Dqn_V2I struct Dqn_V2I
{ {
int32_t x, y; int32_t x, y;
@ -71,6 +76,18 @@ struct Dqn_V2
Dqn_V2 &operator+=(Dqn_V2 other) { *this = *this + other; return *this; } 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 struct Dqn_V3
{ {
Dqn_f32 x, y, z; Dqn_f32 x, y, z;
@ -106,6 +123,18 @@ struct Dqn_V3
Dqn_V3 &operator+=(Dqn_V3 other) { *this = *this + other; return *this; } 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 union Dqn_V4
{ {
struct { Dqn_f32 x, y, z, w; }; 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; }
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 // NOTE: Column major matrix
struct Dqn_M4 struct Dqn_M4
{ {
Dqn_f32 columns[4][4]; 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_f32 Dqn_V4Dot(Dqn_V4 a, Dqn_V4 b);
DQN_API Dqn_M4 Dqn_M4_Identity(); 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) #if !defined(DQN_NO_FSTRING8)
DQN_API Dqn_FString8<256> Dqn_M4_ColumnMajorString(Dqn_M4 mat); DQN_API Dqn_FString8<256> Dqn_M4_ColumnMajorString(Dqn_M4 mat);
#endif #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 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_Union(Dqn_Rect a, Dqn_Rect b);
DQN_API Dqn_Rect Dqn_Rect_FromRectI32(Dqn_RectI32 a); DQN_API Dqn_Rect Dqn_Rect_FromRectI32(Dqn_RectI32 a);
DQN_API Dqn_V2I Dqn_RectI32_Size(Dqn_RectI32 rect); 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_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); DQN_API Dqn_f32 Dqn_Lerp_F32(Dqn_f32 a, Dqn_f32 t, Dqn_f32 b);
#endif // !defined(DQN_NO_MATH)

View File

@ -29,54 +29,36 @@
#define DQN_LEAK_TRACE_UNUSED #define DQN_LEAK_TRACE_UNUSED
#endif #endif
typedef struct Dqn_LeakTrace { struct Dqn_LeakTrace
void *ptr; ///< The pointer we are tracking {
Dqn_usize size; ///< Size of the allocation void *ptr; // The pointer we are tracking
Dqn_CallSite call_site; ///< Call site where the allocation was allocated Dqn_usize size; // Size of the allocation
bool freed; ///< True if this pointer has been freed Dqn_CallSite call_site; // Call site where the allocation was allocated
Dqn_usize freed_size; ///< Size of the allocation that has been freed bool freed; // True if this pointer has been freed
Dqn_CallSite freed_call_site; ///< Call site where the allocation was freed Dqn_usize freed_size; // Size of the allocation that has been freed
} Dqn_LeakTrace; 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_AllocProc(DQN_LEAK_TRACE_FUNCTION size_t size, uint8_t align, Dqn_ZeroMem zero_mem, 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); typedef void Dqn_Allocator_DeallocProc(DQN_LEAK_TRACE_FUNCTION void *ptr, size_t size, void *user_context);
typedef struct Dqn_Allocator { struct Dqn_Allocator
void *user_context; ///< User assigned pointer that is passed into the allocator functions {
Dqn_Allocator_AllocProc *alloc; ///< Memory allocating routine void *user_context; // User assigned pointer that is passed into the allocator functions
Dqn_Allocator_DeallocProc *dealloc; ///< Memory deallocating routine Dqn_Allocator_AllocProc *alloc; // Memory allocating routine
} Dqn_Allocator; Dqn_Allocator_DeallocProc *dealloc; // Memory deallocating routine
};
/// Allocate bytes from the given allocator // NOTE: Macros ==================================================================================
/// @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
#define Dqn_Allocator_Alloc(allocator, size, align, zero_mem) Dqn_Allocator_Alloc_(DQN_LEAK_TRACE allocator, size, align, zero_mem) #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) #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_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) #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 ========================================================================== // NOTE: [$VMEM] Dqn_VMem ==========================================================================
enum Dqn_VMemCommit enum Dqn_VMemCommit
{ {
@ -86,21 +68,23 @@ enum Dqn_VMemCommit
enum Dqn_VMemPage 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, Dqn_VMemPage_NoAccess = 1 << 0,
/// Only read permitted on the page. // Only read permitted on the page.
Dqn_VMemPage_Read = 1 << 1, Dqn_VMemPage_Read = 1 << 1,
/// Only write permitted on the page. On Windows this is not supported and will be promoted to // Only write permitted on the page. On Windows this is not supported and
/// read+write permissions. // will be promoted to read+write permissions.
Dqn_VMemPage_Write = 1 << 2, Dqn_VMemPage_Write = 1 << 2,
Dqn_VMemPage_ReadWrite = Dqn_VMemPage_Read | Dqn_VMemPage_Write, Dqn_VMemPage_ReadWrite = Dqn_VMemPage_Read | Dqn_VMemPage_Write,
/// Modifier used in conjunction with previous flags. Raises exception on first access to the // Modifier used in conjunction with previous flags. Raises exception on
/// page, then, the underlying protection flags are active. This is supported on Windows, on // first access to the page, then, the underlying protection flags are
/// other OS's using this flag will set the OS equivalent of Dqn_VMemPage_NoAccess. // 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, 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. // 64GB) since the arena only commits as much as needed.
// //
// NOTE: API // NOTE: API
//
// @proc Dqn_Arena_Grow // @proc Dqn_Arena_Grow
// @desc Grow the arena's capacity by allocating a block of memory with the // @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 // 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. // pages from the OS.
// @param flags[in] Bit flags from 'Dqn_ArenaBlockFlags', set to 0 if none // @param flags[in] Bit flags from 'Dqn_ArenaBlockFlags', set to 0 if none
// @return The block of memory that // @return The block of memory that
//
// @proc Dqn_Arena_Allocate, Dqn_Arena_New, Dqn_Arena_NewArray, // @proc Dqn_Arena_Allocate, Dqn_Arena_New, Dqn_Arena_NewArray,
// Dqn_Arena_NewArrayWithBlock, // Dqn_Arena_NewArrayWithBlock,
// @desc Allocate byte/objects // @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 // `NewArray` allocates an array of objects
// `NewArrayWithBlock` allocates an array of objects from the given memory 'block' // `NewArrayWithBlock` allocates an array of objects from the given memory 'block'
// @return A pointer to the allocated bytes/object. Null pointer on failure // @return A pointer to the allocated bytes/object. Null pointer on failure
//
// @proc Dqn_Arena_Copy, Dqn_Arena_CopyZ // @proc Dqn_Arena_Copy, Dqn_Arena_CopyZ
// @desc Allocate a copy of an object's bytes. The 'Z' variant adds // @desc Allocate a copy of an object's bytes. The 'Z' variant adds
// a null-terminating byte at the end of the stream. // a null-terminating byte at the end of the stream.
// @return A pointer to the allocated object. Null pointer on failure. // @return A pointer to the allocated object. Null pointer on failure.
//
// @proc Dqn_Arena_Reset // @proc Dqn_Arena_Reset
// @desc Set the arena's current block to the first block in the linked list // @desc Set the arena's current block to the first block in the linked list
// of blocks and mark all blocks free. // of blocks and mark all blocks free.
// @param[in] zero_mem When yes, the memory is cleared using DQN_MEMSET with the // @param[in] zero_mem When yes, the memory is cleared using DQN_MEMSET with the
// value of DQN_MEMSET_BYTE // value of DQN_MEMSET_BYTE
//
// @proc Dqn_Arena_Free // @proc Dqn_Arena_Free
// @desc Free the arena returning all memory back to the OS // @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 // @param[in] zero_mem: When true, the memory is cleared using DQN_MEMSET with
// the value of DQN_MEMSET_BYTE // the value of DQN_MEMSET_BYTE
//
// @proc Dqn_Arena_BeginTempMemory // @proc Dqn_Arena_BeginTempMemory
// @desc Begin an allocation scope where all allocations between begin and end // @desc Begin an allocation scope where all allocations between begin and end
// calls will be reverted. Useful for short-lived or highly defined lifetime // calls will be reverted. Useful for short-lived or highly defined lifetime
// allocations. An allocation scope is invalidated if the arena is freed // allocations. An allocation scope is invalidated if the arena is freed
// between the begin and end call. // between the begin and end call.
//
// @proc Dqn_Arena_EndTempMemory // @proc Dqn_Arena_EndTempMemory
// @desc End an allocation scope previously begun by calling begin scope. // @desc End an allocation scope previously begun by calling begin scope.
//
// @proc Dqn_Arena_StatString // @proc Dqn_Arena_StatString
// @desc Dump the stats of the given arena to a string // @desc Dump the stats of the given arena to a string
// @param[in] arena The arena to dump stats for // @param[in] arena The arena to dump stats for
// @return A stack allocated string containing the stats of the arena // @return A stack allocated string containing the stats of the arena
//
// @proc Dqn_Arena_LogStats // @proc Dqn_Arena_LogStats
// @desc Dump the stats of the given arena to the memory log-stream. // @desc Dump the stats of the given arena to the memory log-stream.
// @param[in] arena The arena to dump stats for // @param[in] arena The arena to dump stats for
@ -211,29 +194,29 @@ enum Dqn_ArenaBlockFlags
struct Dqn_ArenaStat struct Dqn_ArenaStat
{ {
Dqn_usize capacity; ///< Total allocating capacity of the arena in bytes Dqn_usize capacity; // Total allocating capacity of the arena in bytes
Dqn_usize used; ///< Total amount of bytes used in the arena 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 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 uint32_t blocks; // Number of memory blocks in the arena
Dqn_usize syscalls; ///< Number of memory allocation syscalls into the OS Dqn_usize syscalls; // Number of memory allocation syscalls into the OS
Dqn_usize capacity_hwm; ///< High-water mark for 'capacity' Dqn_usize capacity_hwm; // High-water mark for 'capacity'
Dqn_usize used_hwm; ///< High-water mark for 'used' Dqn_usize used_hwm; // High-water mark for 'used'
Dqn_usize wasted_hwm; ///< High-water mark for 'wasted' Dqn_usize wasted_hwm; // High-water mark for 'wasted'
uint32_t blocks_hwm; ///< High-water mark for 'blocks' uint32_t blocks_hwm; // High-water mark for 'blocks'
}; };
struct Dqn_ArenaBlock struct Dqn_ArenaBlock
{ {
struct Dqn_Arena *arena; ///< Arena that owns this block struct Dqn_Arena *arena; // Arena that owns this block
void *memory; ///< Backing memory of the block void *memory; // Backing memory of the block
Dqn_usize size; ///< Size 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 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 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_usize commit; // Number of bytes in the block physically backed by pages
Dqn_ArenaBlock *prev; ///< Previous linked block Dqn_ArenaBlock *prev; // Previous linked block
Dqn_ArenaBlock *next; ///< Next linked block Dqn_ArenaBlock *next; // Next linked block
uint8_t flags; ///< Bit field for 'Dqn_ArenaBlockFlags' uint8_t flags; // Bit field for 'Dqn_ArenaBlockFlags'
}; };
struct Dqn_ArenaStatString struct Dqn_ArenaStatString
@ -246,21 +229,21 @@ struct Dqn_Arena
{ {
bool use_after_free_guard; bool use_after_free_guard;
uint32_t temp_memory_count; uint32_t temp_memory_count;
Dqn_String8 label; ///< Optional label to describe the arena Dqn_String8 label; // Optional label to describe the arena
Dqn_ArenaBlock *head; ///< Active block the arena is allocating from Dqn_ArenaBlock *head; // Active block the arena is allocating from
Dqn_ArenaBlock *curr; ///< 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_ArenaBlock *tail; // Last block in the linked list of blocks
Dqn_ArenaStat stats; ///< Current arena stats, reset when reset usage is invoked. Dqn_ArenaStat stats; // Current arena stats, reset when reset usage is invoked.
}; };
struct Dqn_ArenaTempMemory struct Dqn_ArenaTempMemory
{ {
Dqn_Arena *arena; ///< Arena the scope is for Dqn_Arena *arena; // Arena the scope is for
Dqn_ArenaBlock *head; ///< Head block of the arena at the beginning of the scope 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 *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_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_usize curr_used; // Current used amount of the current block
Dqn_ArenaStat stats; ///< Stats of the arena at the beginning of the scope Dqn_ArenaStat stats; // Stats of the arena at the beginning of the scope
}; };
// Automatically begin and end a temporary memory scope on object construction // Automatically begin and end a temporary memory scope on object construction
@ -279,10 +262,10 @@ struct Dqn_ArenaTempMemoryScope_
enum Dqn_ArenaCommit enum Dqn_ArenaCommit
{ {
/// Commit the pages to ensure the block has the requested commit amount. // Commit the pages to ensure the block has the requested commit amount.
/// No-op if the block has sufficient commit space already. // No-op if the block has sufficient commit space already.
Dqn_ArenaCommit_EnsureSpace, 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 ================================================================================ // NOTE: Allocation ================================================================================
@ -326,7 +309,7 @@ struct Dqn_ArenaCatalogItem
struct Dqn_ArenaCatalog 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_Arena *arena;
Dqn_ArenaCatalogItem sentinel; Dqn_ArenaCatalogItem sentinel;
uint16_t arena_count; uint16_t arena_count;