More fixes

This commit is contained in:
doylet 2026-03-08 16:05:02 +11:00
parent a8efa666b4
commit 2ef2e8d1e2
14 changed files with 258 additions and 215 deletions

2
.clangd Normal file
View File

@ -0,0 +1,2 @@
CompileFlags:
Add: [-D_CLANGD=1]

View File

@ -1,7 +1,7 @@
#define DN_BASE_CPP #define DN_BASE_CPP
#if defined(_CLANGD) #if defined(_CLANGD)
#include "../dn_base.h" #include "../dn.h"
#endif #endif
DN_API bool DN_MemEq(void const *lhs, DN_USize lhs_size, void const *rhs, DN_USize rhs_size) DN_API bool DN_MemEq(void const *lhs, DN_USize lhs_size, void const *rhs, DN_USize rhs_size)
@ -753,7 +753,7 @@ DN_API DN_U64 DN_SaturateCastIntToU64(int val)
return result; return result;
} }
// NOTE: DN_Asan ////////////////////////////////////////////////////////////////////////// //////// // NOTE: DN_Asan
static_assert(DN_IsPowerOfTwoAligned(DN_ASAN_POISON_GUARD_SIZE, DN_ASAN_POISON_ALIGNMENT), static_assert(DN_IsPowerOfTwoAligned(DN_ASAN_POISON_GUARD_SIZE, DN_ASAN_POISON_ALIGNMENT),
"ASAN poison guard size must be a power-of-two and aligned to ASAN's alignment" "ASAN poison guard size must be a power-of-two and aligned to ASAN's alignment"
"requirement (8 bytes)"); "requirement (8 bytes)");
@ -851,12 +851,21 @@ static DN_ArenaBlock *DN_ArenaBlockFromMemFuncs_(DN_U64 reserve, DN_U64 commit,
return result; return result;
} }
static bool DN_ArenaHasPoison_(DN_ArenaFlags flags)
{
DN_MSVC_WARNING_PUSH
DN_MSVC_WARNING_DISABLE(6237) // warning C6237: (<zero> && <expression>) is always zero. <expression> is never evaluated and might have side effects.
bool result = DN_ASAN_POISON && DN_BitIsNotSet(flags, DN_ArenaFlags_NoPoison);
DN_MSVC_WARNING_POP
return result;
}
static DN_ArenaBlock *DN_ArenaBlockFlagsFromMemFuncs_(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs) static DN_ArenaBlock *DN_ArenaBlockFlagsFromMemFuncs_(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs)
{ {
bool track_alloc = (flags & DN_ArenaFlags_NoAllocTrack) == 0; bool track_alloc = (flags & DN_ArenaFlags_NoAllocTrack) == 0;
bool alloc_can_leak = flags & DN_ArenaFlags_AllocCanLeak; bool alloc_can_leak = flags & DN_ArenaFlags_AllocCanLeak;
DN_ArenaBlock *result = DN_ArenaBlockFromMemFuncs_(reserve, commit, track_alloc, alloc_can_leak, mem_funcs); DN_ArenaBlock *result = DN_ArenaBlockFromMemFuncs_(reserve, commit, track_alloc, alloc_can_leak, mem_funcs);
if (result && ((flags & DN_ArenaFlags_NoPoison) == 0)) if (result && DN_ArenaHasPoison_(flags))
DN_ASanPoisonMemoryRegion(DN_Cast(char *) result + DN_ARENA_HEADER_SIZE, result->commit - DN_ARENA_HEADER_SIZE); DN_ASanPoisonMemoryRegion(DN_Cast(char *) result + DN_ARENA_HEADER_SIZE, result->commit - DN_ARENA_HEADER_SIZE);
return result; return result;
} }
@ -888,7 +897,7 @@ DN_API DN_Arena DN_ArenaFromBuffer(void *buffer, DN_USize size, DN_ArenaFlags fl
block->commit = size; block->commit = size;
block->reserve = size; block->reserve = size;
block->used = DN_ARENA_HEADER_SIZE; block->used = DN_ARENA_HEADER_SIZE;
if (block && ((flags & DN_ArenaFlags_NoPoison) == 0)) if (block && DN_ArenaHasPoison_(flags))
DN_ASanPoisonMemoryRegion(DN_Cast(char *) block + DN_ARENA_HEADER_SIZE, block->commit - DN_ARENA_HEADER_SIZE); DN_ASanPoisonMemoryRegion(DN_Cast(char *) block + DN_ARENA_HEADER_SIZE, block->commit - DN_ARENA_HEADER_SIZE);
DN_Arena result = {}; DN_Arena result = {};
@ -914,7 +923,10 @@ static void DN_ArenaBlockDeinit_(DN_Arena const *arena, DN_ArenaBlock *block)
DN_USize release_size = block->reserve; DN_USize release_size = block->reserve;
if (DN_BitIsNotSet(arena->flags, DN_ArenaFlags_NoAllocTrack)) if (DN_BitIsNotSet(arena->flags, DN_ArenaFlags_NoAllocTrack))
DN_LeakTrackDealloc(&g_dn_->leak, block); DN_LeakTrackDealloc(&g_dn_->leak, block);
DN_ASanUnpoisonMemoryRegion(block, block->commit);
if (DN_ArenaHasPoison_(arena->flags))
DN_ASanUnpoisonMemoryRegion(block, block->commit);
if (arena->flags & DN_ArenaFlags_MemFuncs) { if (arena->flags & DN_ArenaFlags_MemFuncs) {
if (arena->mem_funcs.type == DN_ArenaMemFuncType_Basic) if (arena->mem_funcs.type == DN_ArenaMemFuncType_Basic)
arena->mem_funcs.basic_dealloc(block); arena->mem_funcs.basic_dealloc(block);
@ -954,8 +966,7 @@ DN_API bool DN_ArenaCommitTo(DN_Arena *arena, DN_U64 pos)
if (!arena->mem_funcs.vmem_commit(commit_ptr, commit_size, DN_MemPage_ReadWrite)) if (!arena->mem_funcs.vmem_commit(commit_ptr, commit_size, DN_MemPage_ReadWrite))
return false; return false;
bool poison = DN_ASAN_POISON && ((arena->flags & DN_ArenaFlags_NoPoison) == 0); if (DN_ArenaHasPoison_(arena->flags))
if (poison)
DN_ASanPoisonMemoryRegion(commit_ptr, commit_size); DN_ASanPoisonMemoryRegion(commit_ptr, commit_size);
curr->commit = end_commit; curr->commit = end_commit;
@ -1003,7 +1014,7 @@ DN_API void *DN_ArenaAlloc(DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZMem
try_alloc_again: try_alloc_again:
DN_ArenaBlock *curr = arena->curr; DN_ArenaBlock *curr = arena->curr;
bool poison = DN_ASAN_POISON && ((arena->flags & DN_ArenaFlags_NoPoison) == 0); bool poison = DN_ArenaHasPoison_(arena->flags);
uint8_t real_align = poison ? DN_Max(align, DN_ASAN_POISON_ALIGNMENT) : align; uint8_t real_align = poison ? DN_Max(align, DN_ASAN_POISON_ALIGNMENT) : align;
DN_U64 offset_pos = DN_AlignUpPowerOfTwo(curr->used, real_align) + (poison ? DN_ASAN_POISON_GUARD_SIZE : 0); DN_U64 offset_pos = DN_AlignUpPowerOfTwo(curr->used, real_align) + (poison ? DN_ASAN_POISON_GUARD_SIZE : 0);
DN_U64 end_pos = offset_pos + size; DN_U64 end_pos = offset_pos + size;
@ -1041,7 +1052,7 @@ DN_API void *DN_ArenaAlloc(DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZMem
arena->stats.info.used += alloc_size; arena->stats.info.used += alloc_size;
arena->stats.hwm.used = DN_Max(arena->stats.hwm.used, arena->stats.info.used); arena->stats.hwm.used = DN_Max(arena->stats.hwm.used, arena->stats.info.used);
if (DN_BitIsNotSet(arena->flags, DN_ArenaFlags_SimAlloc)) if (poison && DN_BitIsNotSet(arena->flags, DN_ArenaFlags_SimAlloc))
DN_ASanUnpoisonMemoryRegion(result, size); DN_ASanUnpoisonMemoryRegion(result, size);
if (z_mem == DN_ZMem_Yes && DN_BitIsNotSet(arena->flags, DN_ArenaFlags_SimAlloc)) { if (z_mem == DN_ZMem_Yes && DN_BitIsNotSet(arena->flags, DN_ArenaFlags_SimAlloc)) {
@ -1096,9 +1107,11 @@ DN_API void DN_ArenaPopTo(DN_Arena *arena, DN_U64 init_used)
arena->stats.info.used -= curr->used; arena->stats.info.used -= curr->used;
arena->curr = curr; arena->curr = curr;
curr->used = used - curr->reserve_sum; curr->used = used - curr->reserve_sum;
char *poison_ptr = (char *)curr + DN_AlignUpPowerOfTwo(curr->used, DN_ASAN_POISON_ALIGNMENT); if (DN_ArenaHasPoison_(arena->flags)) {
DN_USize poison_size = ((char *)curr + curr->commit) - poison_ptr; char *poison_ptr = (char *)curr + DN_AlignUpPowerOfTwo(curr->used, DN_ASAN_POISON_ALIGNMENT);
DN_ASanPoisonMemoryRegion(poison_ptr, poison_size); DN_USize poison_size = ((char *)curr + curr->commit) - poison_ptr;
DN_ASanPoisonMemoryRegion(poison_ptr, poison_size);
}
arena->stats.info.used += curr->used; arena->stats.info.used += curr->used;
} }
@ -1332,7 +1345,7 @@ DN_API DN_ErrSink* DN_ErrSinkBegin_(DN_ErrSink *err, DN_ErrSinkMode mode, DN_Cal
if (err->stack_size == DN_ArrayCountU(err->stack)) { if (err->stack_size == DN_ArrayCountU(err->stack)) {
DN_Str8Builder builder = DN_Str8BuilderFromArena(err->arena); DN_Str8Builder builder = DN_Str8BuilderFromArena(err->arena);
for (DN_ForItSize(it, DN_ErrSinkNode, err->stack, err->stack_size)) for (DN_ForItSize(it, DN_ErrSinkNode, err->stack, err->stack_size))
DN_Str8BuilderAppendF(&builder, " [%04zu] %S:%u %.*s\n", it.index, it.data->call_site.file, it.data->call_site.line, DN_Str8PrintFmt(it.data->call_site.function)); DN_Str8BuilderAppendF(&builder, " [%04zu] %.*s:%u %.*s\n", it.index, DN_Str8PrintFmt(it.data->call_site.file), it.data->call_site.line, DN_Str8PrintFmt(it.data->call_site.function));
DN_Str8 msg = DN_Str8BuilderBuild(&builder, err->arena); DN_Str8 msg = DN_Str8BuilderBuild(&builder, err->arena);
DN_AssertF(err->stack_size < DN_ArrayCountU(err->stack), "Error sink has run out of error scopes, potential leak. Scopes were\n%.*s", DN_Str8PrintFmt(msg)); DN_AssertF(err->stack_size < DN_ArrayCountU(err->stack), "Error sink has run out of error scopes, potential leak. Scopes were\n%.*s", DN_Str8PrintFmt(msg));
DN_ArenaPopTo(err->arena, arena_pos); DN_ArenaPopTo(err->arena, arena_pos);
@ -4236,17 +4249,19 @@ DN_API DN_LogPrefixSize DN_LogMakePrefix(DN_LogStyle style, DN_LogTypeParam type
DN_API void DN_LogSetPrintFunc(DN_LogPrintFunc *print_func, void *user_data) DN_API void DN_LogSetPrintFunc(DN_LogPrintFunc *print_func, void *user_data)
{ {
g_dn_->print_func = print_func; DN_Core *dn = DN_Get();
g_dn_->print_func_context = user_data; dn->print_func = print_func;
dn->print_func_context = user_data;
} }
DN_API void DN_LogPrint(DN_LogTypeParam type, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, ...) DN_API void DN_LogPrint(DN_LogTypeParam type, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, ...)
{ {
DN_LogPrintFunc *func = g_dn_->print_func; DN_Core *dn = DN_Get();
DN_LogPrintFunc *func = dn->print_func;
if (func) { if (func) {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
func(type, g_dn_->print_func_context, call_site, fmt, args); func(type, dn->print_func_context, call_site, fmt, args);
va_end(args); va_end(args);
} }
} }

View File

@ -1716,10 +1716,10 @@ DN_API DN_LogPrefixSize DN_LogMakePrefix
DN_API void DN_LogSetPrintFunc (DN_LogPrintFunc *print_func, void *user_data); DN_API void DN_LogSetPrintFunc (DN_LogPrintFunc *print_func, void *user_data);
DN_API void DN_LogPrint (DN_LogTypeParam type, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, ...); DN_API void DN_LogPrint (DN_LogTypeParam type, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, ...);
DN_API DN_LogTypeParam DN_LogTypeParamFromType (DN_LogType type); DN_API DN_LogTypeParam DN_LogTypeParamFromType (DN_LogType type);
#define DN_LogDebugF(fmt, ...) DN_LogPrint(DN_LogMakeU32LogTypeParam(DN_LogType_Debug), DN_CALL_SITE, fmt, ##__VA_ARGS__) #define DN_LogDebugF(fmt, ...) DN_LogPrint(DN_LogTypeParamFromType(DN_LogType_Debug), DN_CALL_SITE, fmt, ##__VA_ARGS__)
#define DN_LogInfoF(fmt, ...) DN_LogPrint(DN_LogMakeU32LogTypeParam(DN_LogType_Info), DN_CALL_SITE, fmt, ##__VA_ARGS__) #define DN_LogInfoF(fmt, ...) DN_LogPrint(DN_LogTypeParamFromType(DN_LogType_Info), DN_CALL_SITE, fmt, ##__VA_ARGS__)
#define DN_LogWarningF(fmt, ...) DN_LogPrint(DN_LogMakeU32LogTypeParam(DN_LogType_Warning), DN_CALL_SITE, fmt, ##__VA_ARGS__) #define DN_LogWarningF(fmt, ...) DN_LogPrint(DN_LogTypeParamFromType(DN_LogType_Warning), DN_CALL_SITE, fmt, ##__VA_ARGS__)
#define DN_LogErrorF(fmt, ...) DN_LogPrint(DN_LogMakeU32LogTypeParam(DN_LogType_Error), DN_CALL_SITE, fmt, ##__VA_ARGS__) #define DN_LogErrorF(fmt, ...) DN_LogPrint(DN_LogTypeParamFromType(DN_LogType_Error), DN_CALL_SITE, fmt, ##__VA_ARGS__)
// NOTE: OS primitives that the OS layer can provide for the base layer but is optional. // NOTE: OS primitives that the OS layer can provide for the base layer but is optional.
#if defined(DN_FREESTANDING) #if defined(DN_FREESTANDING)

View File

@ -8,7 +8,7 @@
static DN_I32 DN_ASYNC_ThreadEntryPoint_(DN_OSThread *thread) static DN_I32 DN_ASYNC_ThreadEntryPoint_(DN_OSThread *thread)
{ {
DN_OS_ThreadSetName(DN_Str8FromPtr(thread->name.data, thread->name.size)); DN_OS_ThreadSetNameFmt("%.*s", DN_Str8PrintFmt(thread->name));
DN_ASYNCCore *async = DN_Cast(DN_ASYNCCore *) thread->user_context; DN_ASYNCCore *async = DN_Cast(DN_ASYNCCore *) thread->user_context;
DN_Ring *ring = &async->ring; DN_Ring *ring = &async->ring;
for (;;) { for (;;) {
@ -52,9 +52,8 @@ DN_API void DN_ASYNC_Init(DN_ASYNCCore *async, char *base, DN_USize base_size, D
async->thread_count = threads_size; async->thread_count = threads_size;
async->threads = threads; async->threads = threads;
for (DN_ForIndexU(index, async->thread_count)) { for (DN_ForIndexU(index, async->thread_count)) {
DN_OSThread *thread = async->threads + index; DN_OSThread *thread = async->threads + index;
DN_FmtAppend(thread->name.data, &thread->name.size, DN_ArrayCountU(thread->name.data), "ASYNC W%zu", index); DN_OS_ThreadInit(thread, DN_ASYNC_ThreadEntryPoint_, nullptr, async);
DN_OS_ThreadInit(thread, DN_ASYNC_ThreadEntryPoint_, async);
} }
} }

View File

@ -686,8 +686,8 @@ void DN_Demo()
// The returned string's 'size' member variable does *not* include this // The returned string's 'size' member variable does *not* include this
// additional null-terminating byte. // additional null-terminating byte.
{ {
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str8 string = DN_Str8FromArena(scratch.arena, /*size*/ 1, DN_ZMem_Yes); DN_Str8 string = DN_Str8AllocArena(scratch.arena, /*size*/ 1, DN_ZMem_Yes);
DN_Assert(string.size == 1); DN_Assert(string.size == 1);
DN_Assert(string.data[string.size] == 0); // It is null-terminated! DN_Assert(string.data[string.size] == 0); // It is null-terminated!
DN_TCScratchEnd(&scratch); DN_TCScratchEnd(&scratch);

View File

@ -1,6 +1,8 @@
#define DN_NET_CURL_CPP #define DN_NET_CURL_CPP
#if defined(_CLANGD) #if defined(_CLANGD)
#define DN_H_WITH_OS 1
#include "../dn.h"
#include "dn_net.h" #include "dn_net.h"
#include "dn_net_curl.h" #include "dn_net_curl.h"
#endif #endif
@ -88,7 +90,7 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
{ {
DN_NETCore *net = DN_Cast(DN_NETCore *) thread->user_context; DN_NETCore *net = DN_Cast(DN_NETCore *) thread->user_context;
DN_NETCurlCore *curl = DN_Cast(DN_NETCurlCore *) net->context; DN_NETCurlCore *curl = DN_Cast(DN_NETCurlCore *) net->context;
DN_OS_ThreadSetName(DN_Str8FromPtr(curl->thread.name.data, curl->thread.name.size)); DN_OS_ThreadSetNameFmt("%.*s", DN_Str8PrintFmt(curl->thread.name));
while (!curl->kill_thread) { while (!curl->kill_thread) {
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0); DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
@ -127,7 +129,7 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
DN_Str8 payload = {}; DN_Str8 payload = {};
for (DN_OS_MutexScope(&curl->ring_mutex)) { for (DN_OS_MutexScope(&curl->ring_mutex)) {
DN_Assert(DN_RingHasData(&curl->ring, event.ws_send_size)); DN_Assert(DN_RingHasData(&curl->ring, event.ws_send_size));
payload = DN_Str8FromArena(tmem.arena, event.ws_send_size, DN_ZMem_No); payload = DN_Str8AllocArena(tmem.arena, event.ws_send_size, DN_ZMem_No);
DN_RingRead(&curl->ring, payload.data, payload.size); DN_RingRead(&curl->ring, payload.data, payload.size);
} }
@ -300,7 +302,7 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
// NOTE: Allocate and read (we use meta->bytesleft as per comment from initial recv) // NOTE: Allocate and read (we use meta->bytesleft as per comment from initial recv)
if (meta->bytesleft) { if (meta->bytesleft) {
DN_Str8 buffer = DN_Str8FromArena(&req->arena, meta->bytesleft, DN_ZMem_No); DN_Str8 buffer = DN_Str8AllocArena(&req->arena, meta->bytesleft, DN_ZMem_No);
DN_Assert(buffer.size == DN_Cast(DN_USize)meta->bytesleft); DN_Assert(buffer.size == DN_Cast(DN_USize)meta->bytesleft);
receive_result = curl_ws_recv(curl_req->handle, buffer.data, buffer.size, &buffer.size, &meta); receive_result = curl_ws_recv(curl_req->handle, buffer.data, buffer.size, &buffer.size, &meta);
DN_Assert(buffer.size == DN_Cast(DN_USize)meta->len); DN_Assert(buffer.size == DN_Cast(DN_USize)meta->len);
@ -405,7 +407,7 @@ void DN_NET_CurlInit(DN_NETCore *net, char *base, DN_U64 base_size)
curl->thread_curlm = DN_Cast(CURLM *) curl_multi_init(); curl->thread_curlm = DN_Cast(CURLM *) curl_multi_init();
DN_FmtAppend(curl->thread.name.data, &curl->thread.name.size, sizeof(curl->thread.name.data), "NET (CURL)"); DN_FmtAppend(curl->thread.name.data, &curl->thread.name.size, sizeof(curl->thread.name.data), "NET (CURL)");
DN_OS_ThreadInit(&curl->thread, DN_NET_CurlThreadEntryPoint_, net); DN_OS_ThreadInit(&curl->thread, DN_NET_CurlThreadEntryPoint_, nullptr, net);
} }
void DN_NET_CurlDeinit(DN_NETCore *net) void DN_NET_CurlDeinit(DN_NETCore *net)

View File

@ -39,12 +39,12 @@ struct DN_RefImplCPUReport {
int brandSize_ = 0; int brandSize_ = 0;
bool isIntel_ = false; bool isIntel_ = false;
bool isAMD_ = false; bool isAMD_ = false;
uint32_t f_1_ECX_ = 0; DN_U32 f_1_ECX_ = 0;
uint32_t f_1_EDX_ = 0; DN_U32 f_1_EDX_ = 0;
uint32_t f_7_EBX_ = 0; DN_U32 f_7_EBX_ = 0;
uint32_t f_7_ECX_ = 0; DN_U32 f_7_ECX_ = 0;
uint32_t f_81_ECX_ = 0; DN_U32 f_81_ECX_ = 0;
uint32_t f_81_EDX_ = 0; DN_U32 f_81_EDX_ = 0;
int data_[400][4] = {}; int data_[400][4] = {};
size_t dataSize_ = 0; size_t dataSize_ = 0;
int extdata_[400][4] = {}; int extdata_[400][4] = {};
@ -500,7 +500,7 @@ static DN_UTCore DN_Tests_Bin()
DN_UT_Assert(&test, !result.success); DN_UT_Assert(&test, !result.success);
} }
uint32_t number = 0xd095f6; DN_U32 number = 0xd095f6;
for (DN_UT_Test(&test, "Convert %x to string", number)) { for (DN_UT_Test(&test, "Convert %x to string", number)) {
DN_Str8 number_hex = DN_HexFromBytesPtrArena(&number, sizeof(number), scratch.arena); DN_Str8 number_hex = DN_HexFromBytesPtrArena(&number, sizeof(number), scratch.arena);
DN_UT_AssertF(&test, DN_Str8Eq(number_hex, DN_Str8Lit("f695d000")), "number_hex=%.*s", DN_Str8PrintFmt(number_hex)); DN_UT_AssertF(&test, DN_Str8Eq(number_hex, DN_Str8Lit("f695d000")), "number_hex=%.*s", DN_Str8PrintFmt(number_hex));
@ -531,301 +531,301 @@ static DN_UTCore DN_Tests_BinarySearch()
DN_UT_LogF(&result, "DN_BinarySearch\n"); DN_UT_LogF(&result, "DN_BinarySearch\n");
{ {
for (DN_UT_Test(&result, "Search array of 1 item")) { for (DN_UT_Test(&result, "Search array of 1 item")) {
uint32_t array[] = {1}; DN_U32 array[] = {1};
DN_BinarySearchResult search = {}; DN_BinarySearchResult search = {};
// NOTE: Match ============================================================================= // NOTE: Match =============================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 1); DN_UT_Assert(&result, search.index == 1);
// NOTE: Lower bound ======================================================================= // NOTE: Lower bound =======================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 1); DN_UT_Assert(&result, search.index == 1);
// NOTE: Upper bound ======================================================================= // NOTE: Upper bound =======================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 1); DN_UT_Assert(&result, search.index == 1);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 1); DN_UT_Assert(&result, search.index == 1);
} }
for (DN_UT_Test(&result, "Search array of 2 items")) { for (DN_UT_Test(&result, "Search array of 2 items")) {
uint32_t array[] = {1}; DN_U32 array[] = {1};
DN_BinarySearchResult search = {}; DN_BinarySearchResult search = {};
// NOTE: Match ============================================================================= // NOTE: Match =============================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 1); DN_UT_Assert(&result, search.index == 1);
// NOTE: Lower bound ======================================================================= // NOTE: Lower bound =======================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 1); DN_UT_Assert(&result, search.index == 1);
// NOTE: Upper bound ======================================================================= // NOTE: Upper bound =======================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 1); DN_UT_Assert(&result, search.index == 1);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 1); DN_UT_Assert(&result, search.index == 1);
} }
for (DN_UT_Test(&result, "Search array of 3 items")) { for (DN_UT_Test(&result, "Search array of 3 items")) {
uint32_t array[] = {1, 2, 3}; DN_U32 array[] = {1, 2, 3};
DN_BinarySearchResult search = {}; DN_BinarySearchResult search = {};
// NOTE: Match ============================================================================= // NOTE: Match =============================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 1); DN_UT_Assert(&result, search.index == 1);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 2); DN_UT_Assert(&result, search.index == 2);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 3); DN_UT_Assert(&result, search.index == 3);
// NOTE: Lower bound ======================================================================= // NOTE: Lower bound =======================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 1); DN_UT_Assert(&result, search.index == 1);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 2); DN_UT_Assert(&result, search.index == 2);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 3); DN_UT_Assert(&result, search.index == 3);
// NOTE: Upper bound ======================================================================= // NOTE: Upper bound =======================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 1); DN_UT_Assert(&result, search.index == 1);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 2); DN_UT_Assert(&result, search.index == 2);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 3); DN_UT_Assert(&result, search.index == 3);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 3); DN_UT_Assert(&result, search.index == 3);
} }
for (DN_UT_Test(&result, "Search array of 4 items")) { for (DN_UT_Test(&result, "Search array of 4 items")) {
uint32_t array[] = {1, 2, 3, 4}; DN_U32 array[] = {1, 2, 3, 4};
DN_BinarySearchResult search = {}; DN_BinarySearchResult search = {};
// NOTE: Match ============================================================================= // NOTE: Match =============================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 1); DN_UT_Assert(&result, search.index == 1);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 2); DN_UT_Assert(&result, search.index == 2);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 3); DN_UT_Assert(&result, search.index == 3);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 5U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 5U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 4); DN_UT_Assert(&result, search.index == 4);
// NOTE: Lower bound ======================================================================= // NOTE: Lower bound =======================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 1); DN_UT_Assert(&result, search.index == 1);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 2); DN_UT_Assert(&result, search.index == 2);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 3); DN_UT_Assert(&result, search.index == 3);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 5U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 5U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 4); DN_UT_Assert(&result, search.index == 4);
// NOTE: Upper bound ======================================================================= // NOTE: Upper bound =======================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 1); DN_UT_Assert(&result, search.index == 1);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 2); DN_UT_Assert(&result, search.index == 2);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 3); DN_UT_Assert(&result, search.index == 3);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 4); DN_UT_Assert(&result, search.index == 4);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 5U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 5U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 4); DN_UT_Assert(&result, search.index == 4);
} }
for (DN_UT_Test(&result, "Search array with duplicate items")) { for (DN_UT_Test(&result, "Search array with duplicate items")) {
uint32_t array[] = {1, 1, 2, 2, 3}; DN_U32 array[] = {1, 1, 2, 2, 3};
DN_BinarySearchResult search = {}; DN_BinarySearchResult search = {};
// NOTE: Match ============================================================================= // NOTE: Match =============================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 2); DN_UT_Assert(&result, search.index == 2);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 4); DN_UT_Assert(&result, search.index == 4);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_Match); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_Match);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 5); DN_UT_Assert(&result, search.index == 5);
// NOTE: Lower bound ======================================================================= // NOTE: Lower bound =======================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 2); DN_UT_Assert(&result, search.index == 2);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 4); DN_UT_Assert(&result, search.index == 4);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_LowerBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 4U /*find*/, DN_BinarySearchType_LowerBound);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 5); DN_UT_Assert(&result, search.index == 5);
// NOTE: Upper bound ======================================================================= // NOTE: Upper bound =======================================================================
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 0U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 0); DN_UT_Assert(&result, search.index == 0);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 1U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 2); DN_UT_Assert(&result, search.index == 2);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 2U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, search.found); DN_UT_Assert(&result, search.found);
DN_UT_Assert(&result, search.index == 4); DN_UT_Assert(&result, search.index == 4);
search = DN_BinarySearch<uint32_t>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_UpperBound); search = DN_BinarySearch<DN_U32>(array, DN_ArrayCountU(array), 3U /*find*/, DN_BinarySearchType_UpperBound);
DN_UT_Assert(&result, !search.found); DN_UT_Assert(&result, !search.found);
DN_UT_Assert(&result, search.index == 5); DN_UT_Assert(&result, search.index == 5);
} }
@ -842,7 +842,7 @@ static DN_UTCore DN_Tests_BaseContainers()
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
{ {
DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil); DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil);
uint32_t const MAP_SIZE = 64; DN_U32 const MAP_SIZE = 64;
DN_DSMap<uint64_t> map = DN_DSMapInit<uint64_t>(&arena, MAP_SIZE, DN_DSMapFlags_Nil); DN_DSMap<uint64_t> map = DN_DSMapInit<uint64_t>(&arena, MAP_SIZE, DN_DSMapFlags_Nil);
DN_DEFER DN_DEFER
{ {
@ -895,7 +895,7 @@ static DN_UTCore DN_Tests_BaseContainers()
DN_ArenaTempMemScope temp_mem_scope = DN_ArenaTempMemScope(scratch.arena); DN_ArenaTempMemScope temp_mem_scope = DN_ArenaTempMemScope(scratch.arena);
DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil); DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil);
uint32_t const MAP_SIZE = 64; DN_U32 const MAP_SIZE = 64;
DN_DSMap<uint64_t> map = DN_DSMapInit<uint64_t>(&arena, MAP_SIZE, DN_DSMapFlags_Nil); DN_DSMap<uint64_t> map = DN_DSMapInit<uint64_t>(&arena, MAP_SIZE, DN_DSMapFlags_Nil);
DN_DEFER DN_DEFER
{ {
@ -1176,29 +1176,29 @@ static DN_UTCore DN_Tests_BaseContainers()
DN_UT_LogF(&result, "DN_VArray\n"); DN_UT_LogF(&result, "DN_VArray\n");
{ {
{ {
DN_VArray<uint32_t> array = DN_OS_VArrayInitByteSize<uint32_t>(DN_Kilobytes(64)); DN_VArray<DN_U32> array = DN_OS_VArrayInitByteSize<DN_U32>(DN_Kilobytes(64));
DN_DEFER DN_DEFER
{ {
DN_OS_VArrayDeinit(&array); DN_OS_VArrayDeinit(&array);
}; };
for (DN_UT_Test(&result, "Test adding an array of items to the array")) { for (DN_UT_Test(&result, "Test adding an array of items to the array")) {
uint32_t array_literal[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; DN_U32 array_literal[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
DN_OS_VArrayAddArray<uint32_t>(&array, array_literal, DN_ArrayCountU(array_literal)); DN_OS_VArrayAddArray<DN_U32>(&array, array_literal, DN_ArrayCountU(array_literal));
DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal));
DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0);
} }
for (DN_UT_Test(&result, "Test stable erase, 1 item, the '2' value from the array")) { for (DN_UT_Test(&result, "Test stable erase, 1 item, the '2' value from the array")) {
DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, 1 /*count*/, DN_ArrayErase_Stable); DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, 1 /*count*/, DN_ArrayErase_Stable);
uint32_t array_literal[] = {0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; DN_U32 array_literal[] = {0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal));
DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0);
} }
for (DN_UT_Test(&result, "Test unstable erase, 1 item, the '1' value from the array")) { for (DN_UT_Test(&result, "Test unstable erase, 1 item, the '1' value from the array")) {
DN_OS_VArrayEraseRange(&array, 1 /*begin_index*/, 1 /*count*/, DN_ArrayErase_Unstable); DN_OS_VArrayEraseRange(&array, 1 /*begin_index*/, 1 /*count*/, DN_ArrayErase_Unstable);
uint32_t array_literal[] = {0, 15, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; DN_U32 array_literal[] = {0, 15, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal));
DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0);
} }
@ -1206,7 +1206,7 @@ static DN_UTCore DN_Tests_BaseContainers()
DN_ArrayErase erase_enums[] = {DN_ArrayErase_Stable, DN_ArrayErase_Unstable}; DN_ArrayErase erase_enums[] = {DN_ArrayErase_Stable, DN_ArrayErase_Unstable};
for (DN_UT_Test(&result, "Test un/stable erase, OOB")) { for (DN_UT_Test(&result, "Test un/stable erase, OOB")) {
for (DN_ArrayErase erase : erase_enums) { for (DN_ArrayErase erase : erase_enums) {
uint32_t array_literal[] = {0, 15, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; DN_U32 array_literal[] = {0, 15, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
DN_OS_VArrayEraseRange(&array, DN_ArrayCountU(array_literal) /*begin_index*/, DN_ArrayCountU(array_literal) + 100 /*count*/, erase); DN_OS_VArrayEraseRange(&array, DN_ArrayCountU(array_literal) /*begin_index*/, DN_ArrayCountU(array_literal) + 100 /*count*/, erase);
DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal));
DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0);
@ -1215,51 +1215,51 @@ static DN_UTCore DN_Tests_BaseContainers()
for (DN_UT_Test(&result, "Test flipped begin/end index stable erase, 2 items, the '15, 3' value from the array")) { for (DN_UT_Test(&result, "Test flipped begin/end index stable erase, 2 items, the '15, 3' value from the array")) {
DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, -2 /*count*/, DN_ArrayErase_Stable); DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, -2 /*count*/, DN_ArrayErase_Stable);
uint32_t array_literal[] = {0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; DN_U32 array_literal[] = {0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14};
DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal));
DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0);
} }
for (DN_UT_Test(&result, "Test flipped begin/end index unstable erase, 2 items, the '4, 5' value from the array")) { for (DN_UT_Test(&result, "Test flipped begin/end index unstable erase, 2 items, the '4, 5' value from the array")) {
DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, -2 /*count*/, DN_ArrayErase_Unstable); DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, -2 /*count*/, DN_ArrayErase_Unstable);
uint32_t array_literal[] = {0, 13, 14, 6, 7, 8, 9, 10, 11, 12}; DN_U32 array_literal[] = {0, 13, 14, 6, 7, 8, 9, 10, 11, 12};
DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal));
DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0);
} }
for (DN_UT_Test(&result, "Test stable erase range, 2+1 (oob) item, the '13, 14, +1 OOB' value from the array")) { for (DN_UT_Test(&result, "Test stable erase range, 2+1 (oob) item, the '13, 14, +1 OOB' value from the array")) {
DN_OS_VArrayEraseRange(&array, 8 /*begin_index*/, 3 /*count*/, DN_ArrayErase_Stable); DN_OS_VArrayEraseRange(&array, 8 /*begin_index*/, 3 /*count*/, DN_ArrayErase_Stable);
uint32_t array_literal[] = {0, 13, 14, 6, 7, 8, 9, 10}; DN_U32 array_literal[] = {0, 13, 14, 6, 7, 8, 9, 10};
DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal));
DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0);
} }
for (DN_UT_Test(&result, "Test unstable erase range, 3+1 (oob) item, the '11, 12, +1 OOB' value from the array")) { for (DN_UT_Test(&result, "Test unstable erase range, 3+1 (oob) item, the '11, 12, +1 OOB' value from the array")) {
DN_OS_VArrayEraseRange(&array, 6 /*begin_index*/, 3 /*count*/, DN_ArrayErase_Unstable); DN_OS_VArrayEraseRange(&array, 6 /*begin_index*/, 3 /*count*/, DN_ArrayErase_Unstable);
uint32_t array_literal[] = {0, 13, 14, 6, 7, 8}; DN_U32 array_literal[] = {0, 13, 14, 6, 7, 8};
DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal));
DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0);
} }
for (DN_UT_Test(&result, "Test stable erase -overflow OOB, erasing the '0, 13' value from the array")) { for (DN_UT_Test(&result, "Test stable erase -overflow OOB, erasing the '0, 13' value from the array")) {
DN_OS_VArrayEraseRange(&array, 1 /*begin_index*/, -DN_ISIZE_MAX /*count*/, DN_ArrayErase_Stable); DN_OS_VArrayEraseRange(&array, 1 /*begin_index*/, -DN_ISIZE_MAX /*count*/, DN_ArrayErase_Stable);
uint32_t array_literal[] = {14, 6, 7, 8}; DN_U32 array_literal[] = {14, 6, 7, 8};
DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal));
DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0);
} }
for (DN_UT_Test(&result, "Test unstable erase +overflow OOB, erasing the '7, 8' value from the array")) { for (DN_UT_Test(&result, "Test unstable erase +overflow OOB, erasing the '7, 8' value from the array")) {
DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, DN_ISIZE_MAX /*count*/, DN_ArrayErase_Unstable); DN_OS_VArrayEraseRange(&array, 2 /*begin_index*/, DN_ISIZE_MAX /*count*/, DN_ArrayErase_Unstable);
uint32_t array_literal[] = {14, 6}; DN_U32 array_literal[] = {14, 6};
DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal)); DN_UT_Assert(&result, array.size == DN_ArrayCountU(array_literal));
DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0); DN_UT_Assert(&result, DN_Memcmp(array.data, array_literal, DN_ArrayCountU(array_literal) * sizeof(array_literal[0])) == 0);
} }
for (DN_UT_Test(&result, "Test adding an array of items after erase")) { for (DN_UT_Test(&result, "Test adding an array of items after erase")) {
uint32_t array_literal[] = {0, 1, 2, 3}; DN_U32 array_literal[] = {0, 1, 2, 3};
DN_OS_VArrayAddArray<uint32_t>(&array, array_literal, DN_ArrayCountU(array_literal)); DN_OS_VArrayAddArray<DN_U32>(&array, array_literal, DN_ArrayCountU(array_literal));
uint32_t expected_literal[] = {14, 6, 0, 1, 2, 3}; DN_U32 expected_literal[] = {14, 6, 0, 1, 2, 3};
DN_UT_Assert(&result, array.size == DN_ArrayCountU(expected_literal)); DN_UT_Assert(&result, array.size == DN_ArrayCountU(expected_literal));
DN_UT_Assert(&result, DN_Memcmp(array.data, expected_literal, DN_ArrayCountU(expected_literal) * sizeof(expected_literal[0])) == 0); DN_UT_Assert(&result, DN_Memcmp(array.data, expected_literal, DN_ArrayCountU(expected_literal) * sizeof(expected_literal[0])) == 0);
} }
@ -1342,7 +1342,7 @@ static DN_UTCore DN_Tests_Intrinsics()
DN_UT_LogF(&result, "DN_Atomic\n"); DN_UT_LogF(&result, "DN_Atomic\n");
{ {
for (DN_UT_Test(&result, "DN_AtomicAddU32")) { for (DN_UT_Test(&result, "DN_AtomicAddU32")) {
uint32_t val = 0; DN_U32 val = 0;
DN_AtomicAddU32(&val, 1); DN_AtomicAddU32(&val, 1);
DN_UT_AssertF(&result, val == 1, "val: %u", val); DN_UT_AssertF(&result, val == 1, "val: %u", val);
} }
@ -1354,7 +1354,7 @@ static DN_UTCore DN_Tests_Intrinsics()
} }
for (DN_UT_Test(&result, "DN_AtomicSubU32")) { for (DN_UT_Test(&result, "DN_AtomicSubU32")) {
uint32_t val = 1; DN_U32 val = 1;
DN_AtomicSubU32(&val, 1); DN_AtomicSubU32(&val, 1);
DN_UT_AssertF(&result, val == 0, "val: %u", val); DN_UT_AssertF(&result, val == 0, "val: %u", val);
} }
@ -1733,7 +1733,7 @@ DN_UTCore DN_Tests_Keccak()
DN_UT_LogF(&result, "DN_KC\n"); DN_UT_LogF(&result, "DN_KC\n");
{ {
for (int hash_type = 0; hash_type < Hash_Count; hash_type++) { for (int hash_type = 0; hash_type < Hash_Count; hash_type++) {
DN_PCG32 rng = DN_PCG32_Init(0xd48e'be21'2af8'733d); DN_PCG32 rng = DN_PCG32Init(0xd48e'be21'2af8'733d);
for (DN_Str8 input : INPUTS) { for (DN_Str8 input : INPUTS) {
DN_UT_BeginF(&result, "%.*s - Input: %.*s", DN_Str8PrintFmt(DN_UT_HASH_STRING_[hash_type]), DN_Cast(int) DN_Min(input.size, 54), input.data); DN_UT_BeginF(&result, "%.*s - Input: %.*s", DN_Str8PrintFmt(DN_UT_HASH_STRING_[hash_type]), DN_Cast(int) DN_Min(input.size, 54), input.data);
DN_Tests_KeccakDispatch_(&result, hash_type, input); DN_Tests_KeccakDispatch_(&result, hash_type, input);
@ -1742,11 +1742,11 @@ DN_UTCore DN_Tests_Keccak()
DN_UT_BeginF(&result, "%.*s - Deterministic random inputs", DN_Str8PrintFmt(DN_UT_HASH_STRING_[hash_type])); DN_UT_BeginF(&result, "%.*s - Deterministic random inputs", DN_Str8PrintFmt(DN_UT_HASH_STRING_[hash_type]));
for (DN_USize index = 0; index < 128; index++) { for (DN_USize index = 0; index < 128; index++) {
char src[4096] = {}; char src[4096] = {};
uint32_t src_size = DN_PCG32_Range(&rng, 0, sizeof(src)); DN_U32 src_size = DN_PCG32Range(&rng, 0, sizeof(src));
for (DN_USize src_index = 0; src_index < src_size; src_index++) for (DN_USize src_index = 0; src_index < src_size; src_index++)
src[src_index] = DN_Cast(char) DN_PCG32_Range(&rng, 0, 255); src[src_index] = DN_Cast(char) DN_PCG32Range(&rng, 0, 255);
DN_Str8 input = DN_Str8FromPtr(src, src_size); DN_Str8 input = DN_Str8FromPtr(src, src_size);
DN_Tests_KeccakDispatch_(&result, hash_type, input); DN_Tests_KeccakDispatch_(&result, hash_type, input);
@ -1764,9 +1764,9 @@ static DN_UTCore DN_Tests_M4()
DN_UT_LogF(&result, "DN_M4\n"); DN_UT_LogF(&result, "DN_M4\n");
{ {
for (DN_UT_Test(&result, "Simple translate and scale matrix")) { for (DN_UT_Test(&result, "Simple translate and scale matrix")) {
DN_M4 translate = DN_M4_TranslateF(1, 2, 3); DN_M4 translate = DN_M4TranslateF(1, 2, 3);
DN_M4 scale = DN_M4_ScaleF(2, 2, 2); DN_M4 scale = DN_M4ScaleF(2, 2, 2);
DN_M4 mul_result = DN_M4_Mul(translate, scale); DN_M4 mul_result = DN_M4Mul(translate, scale);
const DN_M4 EXPECT = { const DN_M4 EXPECT = {
{ {
@ -1780,8 +1780,8 @@ static DN_UTCore DN_Tests_M4()
DN_UT_AssertF(&result, DN_UT_AssertF(&result,
memcmp(mul_result.columns, EXPECT.columns, sizeof(EXPECT)) == 0, memcmp(mul_result.columns, EXPECT.columns, sizeof(EXPECT)) == 0,
"\nresult =\n%s\nexpected =\n%s", "\nresult =\n%s\nexpected =\n%s",
DN_M4_ColumnMajorString(mul_result).data, DN_M4ColumnMajorString(mul_result).data,
DN_M4_ColumnMajorString(EXPECT).data); DN_M4ColumnMajorString(EXPECT).data);
} }
} }
return result; return result;
@ -1944,9 +1944,9 @@ static DN_UTCore DN_Tests_Rect()
DN_UT_LogF(&result, "DN_Rect\n"); DN_UT_LogF(&result, "DN_Rect\n");
{ {
for (DN_UT_Test(&result, "No intersection")) { for (DN_UT_Test(&result, "No intersection")) {
DN_Rect a = DN_Rect_From2V2(DN_V2F32_From1N(0), DN_V2F32_From2N(100, 100)); DN_Rect a = DN_RectFrom2V2(DN_V2F32From1N(0), DN_V2F32From2N(100, 100));
DN_Rect b = DN_Rect_From2V2(DN_V2F32_From2N(200, 0), DN_V2F32_From2N(200, 200)); DN_Rect b = DN_RectFrom2V2(DN_V2F32From2N(200, 0), DN_V2F32From2N(200, 200));
DN_Rect ab = DN_Rect_Intersection(a, b); DN_Rect ab = DN_RectIntersection(a, b);
DN_V2F32 ab_max = ab.pos + ab.size; DN_V2F32 ab_max = ab.pos + ab.size;
DN_UT_AssertF(&result, DN_UT_AssertF(&result,
@ -1959,9 +1959,9 @@ static DN_UTCore DN_Tests_Rect()
} }
for (DN_UT_Test(&result, "A's min intersects B")) { for (DN_UT_Test(&result, "A's min intersects B")) {
DN_Rect a = DN_Rect_From2V2(DN_V2F32_From2N(50, 50), DN_V2F32_From2N(100, 100)); DN_Rect a = DN_RectFrom2V2(DN_V2F32From2N(50, 50), DN_V2F32From2N(100, 100));
DN_Rect b = DN_Rect_From2V2(DN_V2F32_From2N(0, 0), DN_V2F32_From2N(100, 100)); DN_Rect b = DN_RectFrom2V2(DN_V2F32From2N(0, 0), DN_V2F32From2N(100, 100));
DN_Rect ab = DN_Rect_Intersection(a, b); DN_Rect ab = DN_RectIntersection(a, b);
DN_V2F32 ab_max = ab.pos + ab.size; DN_V2F32 ab_max = ab.pos + ab.size;
DN_UT_AssertF(&result, DN_UT_AssertF(&result,
@ -1974,9 +1974,9 @@ static DN_UTCore DN_Tests_Rect()
} }
for (DN_UT_Test(&result, "B's min intersects A")) { for (DN_UT_Test(&result, "B's min intersects A")) {
DN_Rect a = DN_Rect_From2V2(DN_V2F32_From2N(0, 0), DN_V2F32_From2N(100, 100)); DN_Rect a = DN_RectFrom2V2(DN_V2F32From2N(0, 0), DN_V2F32From2N(100, 100));
DN_Rect b = DN_Rect_From2V2(DN_V2F32_From2N(50, 50), DN_V2F32_From2N(100, 100)); DN_Rect b = DN_RectFrom2V2(DN_V2F32From2N(50, 50), DN_V2F32From2N(100, 100));
DN_Rect ab = DN_Rect_Intersection(a, b); DN_Rect ab = DN_RectIntersection(a, b);
DN_V2F32 ab_max = ab.pos + ab.size; DN_V2F32 ab_max = ab.pos + ab.size;
DN_UT_AssertF(&result, DN_UT_AssertF(&result,
@ -1989,9 +1989,9 @@ static DN_UTCore DN_Tests_Rect()
} }
for (DN_UT_Test(&result, "A's max intersects B")) { for (DN_UT_Test(&result, "A's max intersects B")) {
DN_Rect a = DN_Rect_From2V2(DN_V2F32_From2N(-50, -50), DN_V2F32_From2N(100, 100)); DN_Rect a = DN_RectFrom2V2(DN_V2F32From2N(-50, -50), DN_V2F32From2N(100, 100));
DN_Rect b = DN_Rect_From2V2(DN_V2F32_From2N(0, 0), DN_V2F32_From2N(100, 100)); DN_Rect b = DN_RectFrom2V2(DN_V2F32From2N(0, 0), DN_V2F32From2N(100, 100));
DN_Rect ab = DN_Rect_Intersection(a, b); DN_Rect ab = DN_RectIntersection(a, b);
DN_V2F32 ab_max = ab.pos + ab.size; DN_V2F32 ab_max = ab.pos + ab.size;
DN_UT_AssertF(&result, DN_UT_AssertF(&result,
@ -2004,9 +2004,9 @@ static DN_UTCore DN_Tests_Rect()
} }
for (DN_UT_Test(&result, "B's max intersects A")) { for (DN_UT_Test(&result, "B's max intersects A")) {
DN_Rect a = DN_Rect_From2V2(DN_V2F32_From2N(0, 0), DN_V2F32_From2N(100, 100)); DN_Rect a = DN_RectFrom2V2(DN_V2F32From2N(0, 0), DN_V2F32From2N(100, 100));
DN_Rect b = DN_Rect_From2V2(DN_V2F32_From2N(-50, -50), DN_V2F32_From2N(100, 100)); DN_Rect b = DN_RectFrom2V2(DN_V2F32From2N(-50, -50), DN_V2F32From2N(100, 100));
DN_Rect ab = DN_Rect_Intersection(a, b); DN_Rect ab = DN_RectIntersection(a, b);
DN_V2F32 ab_max = ab.pos + ab.size; DN_V2F32 ab_max = ab.pos + ab.size;
DN_UT_AssertF(&result, DN_UT_AssertF(&result,
@ -2019,9 +2019,9 @@ static DN_UTCore DN_Tests_Rect()
} }
for (DN_UT_Test(&result, "B contains A")) { for (DN_UT_Test(&result, "B contains A")) {
DN_Rect a = DN_Rect_From2V2(DN_V2F32_From2N(25, 25), DN_V2F32_From2N(25, 25)); DN_Rect a = DN_RectFrom2V2(DN_V2F32From2N(25, 25), DN_V2F32From2N(25, 25));
DN_Rect b = DN_Rect_From2V2(DN_V2F32_From2N(0, 0), DN_V2F32_From2N(100, 100)); DN_Rect b = DN_RectFrom2V2(DN_V2F32From2N(0, 0), DN_V2F32From2N(100, 100));
DN_Rect ab = DN_Rect_Intersection(a, b); DN_Rect ab = DN_RectIntersection(a, b);
DN_V2F32 ab_max = ab.pos + ab.size; DN_V2F32 ab_max = ab.pos + ab.size;
DN_UT_AssertF(&result, DN_UT_AssertF(&result,
@ -2034,9 +2034,9 @@ static DN_UTCore DN_Tests_Rect()
} }
for (DN_UT_Test(&result, "A contains B")) { for (DN_UT_Test(&result, "A contains B")) {
DN_Rect a = DN_Rect_From2V2(DN_V2F32_From2N(0, 0), DN_V2F32_From2N(100, 100)); DN_Rect a = DN_RectFrom2V2(DN_V2F32From2N(0, 0), DN_V2F32From2N(100, 100));
DN_Rect b = DN_Rect_From2V2(DN_V2F32_From2N(25, 25), DN_V2F32_From2N(25, 25)); DN_Rect b = DN_RectFrom2V2(DN_V2F32From2N(25, 25), DN_V2F32From2N(25, 25));
DN_Rect ab = DN_Rect_Intersection(a, b); DN_Rect ab = DN_RectIntersection(a, b);
DN_V2F32 ab_max = ab.pos + ab.size; DN_V2F32 ab_max = ab.pos + ab.size;
DN_UT_AssertF(&result, DN_UT_AssertF(&result,
@ -2049,9 +2049,9 @@ static DN_UTCore DN_Tests_Rect()
} }
for (DN_UT_Test(&result, "A equals B")) { for (DN_UT_Test(&result, "A equals B")) {
DN_Rect a = DN_Rect_From2V2(DN_V2F32_From2N(0, 0), DN_V2F32_From2N(100, 100)); DN_Rect a = DN_RectFrom2V2(DN_V2F32From2N(0, 0), DN_V2F32From2N(100, 100));
DN_Rect b = a; DN_Rect b = a;
DN_Rect ab = DN_Rect_Intersection(a, b); DN_Rect ab = DN_RectIntersection(a, b);
DN_V2F32 ab_max = ab.pos + ab.size; DN_V2F32 ab_max = ab.pos + ab.size;
DN_UT_AssertF(&result, DN_UT_AssertF(&result,
@ -2132,8 +2132,8 @@ static DN_UTCore DN_Tests_Str8()
} }
for (DN_UT_Test(&result, "Allocate string from arena")) { for (DN_UT_Test(&result, "Allocate string from arena")) {
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str8 string = DN_Str8FromArena(scratch.arena, 2, DN_ZMem_No); DN_Str8 string = DN_Str8AllocArena(scratch.arena, 2, DN_ZMem_No);
DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size); DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size);
DN_TCScratchEnd(&scratch); DN_TCScratchEnd(&scratch);
} }
@ -2538,6 +2538,7 @@ static DN_UTCore DN_Tests_Net()
done = true; done = true;
} }
} }
net_interface.deinit(&net);
DN_ArenaDeinit(&arena); DN_ArenaDeinit(&arena);
} }
#endif // defined(DN_UNIT_TESTS_WITH_NET) #endif // defined(DN_UNIT_TESTS_WITH_NET)

View File

@ -4,7 +4,6 @@
#define DN_H_WITH_OS 1 #define DN_H_WITH_OS 1
#define DN_H_WITH_CORE 1 #define DN_H_WITH_CORE 1
#define DN_H_WITH_MATH 1
#define DN_H_WITH_HASH 1 #define DN_H_WITH_HASH 1
#define DN_H_WITH_HELPERS 1 #define DN_H_WITH_HELPERS 1
#define DN_H_WITH_ASYNC 1 #define DN_H_WITH_ASYNC 1
@ -34,8 +33,8 @@ DN_MSVC_WARNING_PUSH
DN_MSVC_WARNING_DISABLE(6262) // Function uses '29804' bytes of stack. Consider moving some data to heap. DN_MSVC_WARNING_DISABLE(6262) // Function uses '29804' bytes of stack. Consider moving some data to heap.
int main(int, char**) int main(int, char**)
{ {
DN_Core core = {}; DN_Core dn = {};
DN_Init(&core, DN_InitFlags_LogAllFeatures | DN_InitFlags_OS, nullptr); DN_Init(&dn, DN_InitFlags_LogAllFeatures | DN_InitFlags_OS | DN_InitFlags_ThreadContext, nullptr);
DN_Tests_RunSuite(DN_TestsPrint_Yes); DN_Tests_RunSuite(DN_TestsPrint_Yes);
return 0; return 0;
} }

View File

@ -30,9 +30,10 @@ DN_API DN_ArenaMemFuncs DN_ArenaMemFuncsGet(DN_ArenaMemFuncType type)
}; };
case DN_ArenaMemFuncType_VMem: { case DN_ArenaMemFuncType_VMem: {
DN_Assert(g_dn_->init_flags & DN_InitFlags_OS); DN_Core *dn = DN_Get();
DN_Assert(dn->init_flags & DN_InitFlags_OS);
result.type = DN_ArenaMemFuncType_VMem; result.type = DN_ArenaMemFuncType_VMem;
result.vmem_page_size = g_dn_->os.page_size; result.vmem_page_size = dn->os.page_size;
result.vmem_reserve = DN_OS_MemReserve; result.vmem_reserve = DN_OS_MemReserve;
result.vmem_commit = DN_OS_MemCommit; result.vmem_commit = DN_OS_MemCommit;
result.vmem_release = DN_OS_MemRelease; result.vmem_release = DN_OS_MemRelease;
@ -43,8 +44,9 @@ DN_API DN_ArenaMemFuncs DN_ArenaMemFuncsGet(DN_ArenaMemFuncType type)
DN_API DN_ArenaMemFuncs DN_ArenaMemFuncsGetDefaults() DN_API DN_ArenaMemFuncs DN_ArenaMemFuncsGetDefaults()
{ {
DN_Core *dn = DN_Get();
DN_ArenaMemFuncType type = DN_ArenaMemFuncType_Basic; DN_ArenaMemFuncType type = DN_ArenaMemFuncType_Basic;
if (g_dn_->os_init) { if (dn->os_init) {
#if !defined(DN_PLATFORM_EMSCRIPTEN) #if !defined(DN_PLATFORM_EMSCRIPTEN)
type = DN_ArenaMemFuncType_VMem; type = DN_ArenaMemFuncType_VMem;
#endif #endif
@ -55,23 +57,15 @@ DN_API DN_ArenaMemFuncs DN_ArenaMemFuncsGetDefaults()
DN_API DN_Arena DN_ArenaFromHeap(DN_U64 size, DN_ArenaFlags flags) DN_API DN_Arena DN_ArenaFromHeap(DN_U64 size, DN_ArenaFlags flags)
{ {
DN_ArenaMemFuncs mem_funcs = {}; DN_ArenaMemFuncs mem_funcs = DN_ArenaMemFuncsGet(DN_ArenaMemFuncType_Basic);
mem_funcs.type = DN_ArenaMemFuncType_Basic; DN_Arena result = DN_ArenaFromMemFuncs(size, size, flags, mem_funcs);
mem_funcs.basic_alloc = DN_ArenaBasicAllocFromOSHeap;
mem_funcs.basic_dealloc = DN_OS_MemDealloc;
DN_Arena result = DN_ArenaFromMemFuncs(size, size, flags, mem_funcs);
return result; return result;
} }
DN_API DN_Arena DN_ArenaFromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags) DN_API DN_Arena DN_ArenaFromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags)
{ {
DN_ArenaMemFuncs mem_funcs = {}; DN_ArenaMemFuncs mem_funcs = DN_ArenaMemFuncsGet(DN_ArenaMemFuncType_VMem);
mem_funcs.type = DN_ArenaMemFuncType_VMem; DN_Arena result = DN_ArenaFromMemFuncs(reserve, commit, flags, mem_funcs);
mem_funcs.vmem_page_size = g_dn_->os.page_size;
mem_funcs.vmem_reserve = DN_OS_MemReserve;
mem_funcs.vmem_commit = DN_OS_MemCommit;
mem_funcs.vmem_release = DN_OS_MemRelease;
DN_Arena result = DN_ArenaFromMemFuncs(reserve, commit, flags, mem_funcs);
return result; return result;
} }
@ -211,7 +205,8 @@ DN_API void DN_OS_LogPrint(DN_LogTypeParam type, void *user_data, DN_CallSite ca
DN_API void DN_OS_SetLogPrintFuncToOS() DN_API void DN_OS_SetLogPrintFuncToOS()
{ {
DN_LogSetPrintFunc(DN_OS_LogPrint, &g_dn_->os); DN_Core *dn = DN_Get();
DN_LogSetPrintFunc(DN_OS_LogPrint, &dn->os);
} }
// NOTE: Date // NOTE: Date
@ -761,7 +756,7 @@ DN_API DN_V2USize DN_OS_ThreadLaneRange(DN_OSThreadLane *lane, DN_USize values_c
if (thread_has_leftovers) if (thread_has_leftovers)
leftovers_before_this_thread_index = lane->index; leftovers_before_this_thread_index = lane->index;
else else
leftovers_before_this_thread_index = leftovers_before_this_thread_index; leftovers_before_this_thread_index = rem_values;
DN_USize thread_start_index = (values_per_thread * lane->index) + leftovers_before_this_thread_index; DN_USize thread_start_index = (values_per_thread * lane->index) + leftovers_before_this_thread_index;
DN_USize thread_values_count = values_per_thread + (thread_has_leftovers ? 1 : 0); DN_USize thread_values_count = values_per_thread + (thread_has_leftovers ? 1 : 0);
@ -1144,7 +1139,7 @@ bool DN_OS_VArrayReserve(DN_VArray<T> *array, DN_USize count)
return false; return false;
DN_USize real_commit = (array->size + count) * sizeof(T); DN_USize real_commit = (array->size + count) * sizeof(T);
DN_USize aligned_commit = DN_AlignUpPowerOfTwo(real_commit, g_dn_->os.page_size); DN_USize aligned_commit = DN_AlignUpPowerOfTwo(real_commit, DN_Get()->os.page_size);
if (array->commit >= aligned_commit) if (array->commit >= aligned_commit)
return true; return true;
bool result = DN_OS_MemCommit(array->data, aligned_commit, DN_MemPage_ReadWrite); bool result = DN_OS_MemCommit(array->data, aligned_commit, DN_MemPage_ReadWrite);

View File

@ -318,16 +318,17 @@ DN_API DN_U64 DN_OS_PerfCounterFrequency()
return result; return result;
} }
static DN_OSPosixCore *DN_OS_GetPOSIXCore_() static DN_OSPosixCore *DN_OS_PosixGetCore()
{ {
DN_Assert(g_dn_ && g_dn_->os.platform_context); DN_Core *dn = DN_Get();
DN_OSPosixCore *result = DN_Cast(DN_OSPosixCore *)g_dn_->os.platform_context; DN_Assert(dn && dn->os_init);
DN_OSPosixCore *result = DN_Cast(DN_OSPosixCore *)dn->os.platform_context;
return result; return result;
} }
DN_API DN_U64 DN_OS_PerfCounterNow() DN_API DN_U64 DN_OS_PerfCounterNow()
{ {
DN_OSPosixCore *posix = DN_OS_GetPOSIXCore_(); DN_OSPosixCore *posix = DN_OS_PosixGetCore();
struct timespec ts; struct timespec ts;
clock_gettime(posix->clock_monotonic_raw ? CLOCK_MONOTONIC_RAW : CLOCK_MONOTONIC, &ts); clock_gettime(posix->clock_monotonic_raw ? CLOCK_MONOTONIC_RAW : CLOCK_MONOTONIC, &ts);
DN_U64 result = DN_Cast(DN_U64) ts.tv_sec * 1'000'000'000 + DN_Cast(DN_U64) ts.tv_nsec; DN_U64 result = DN_Cast(DN_U64) ts.tv_sec * 1'000'000'000 + DN_Cast(DN_U64) ts.tv_nsec;
@ -1050,7 +1051,7 @@ static DN_U64 DN_OS_PosixSyncPrimitiveToU64(DN_OSPosixSyncPrimitive *primitive)
static DN_OSPosixSyncPrimitive *DN_POSIX_AllocSyncPrimitive_() static DN_OSPosixSyncPrimitive *DN_POSIX_AllocSyncPrimitive_()
{ {
DN_OSPosixCore *posix = DN_OS_GetPOSIXCore_(); DN_OSPosixCore *posix = DN_OS_PosixGetCore();
DN_OSPosixSyncPrimitive *result = nullptr; DN_OSPosixSyncPrimitive *result = nullptr;
pthread_mutex_lock(&posix->sync_primitive_free_list_mutex); pthread_mutex_lock(&posix->sync_primitive_free_list_mutex);
{ {
@ -1070,7 +1071,7 @@ static DN_OSPosixSyncPrimitive *DN_POSIX_AllocSyncPrimitive_()
static void DN_OS_PosixDeallocSyncPrimitive_(DN_OSPosixSyncPrimitive *primitive) static void DN_OS_PosixDeallocSyncPrimitive_(DN_OSPosixSyncPrimitive *primitive)
{ {
if (primitive) { if (primitive) {
DN_OSPosixCore *posix = DN_OS_GetPOSIXCore_(); DN_OSPosixCore *posix = DN_OS_PosixGetCore();
pthread_mutex_lock(&posix->sync_primitive_free_list_mutex); pthread_mutex_lock(&posix->sync_primitive_free_list_mutex);
primitive->next = posix->sync_primitive_free_list; primitive->next = posix->sync_primitive_free_list;
posix->sync_primitive_free_list = primitive; posix->sync_primitive_free_list = primitive;

View File

@ -41,9 +41,9 @@ DN_API void *DN_OS_MemReserve(DN_USize size, DN_MemCommit commit, DN_U32 page_fl
void *result = VirtualAlloc(nullptr, size, flags, os_page_flags); void *result = VirtualAlloc(nullptr, size, flags, os_page_flags);
if (flags & MEM_COMMIT) { if (flags & MEM_COMMIT) {
DN_Assert(g_dn_); DN_Core *dn = DN_Get();
DN_AtomicAddU64(&g_dn_->os.vmem_allocs_total, 1); DN_AtomicAddU64(&dn->os.vmem_allocs_total, 1);
DN_AtomicAddU64(&g_dn_->os.vmem_allocs_frame, 1); DN_AtomicAddU64(&dn->os.vmem_allocs_frame, 1);
} }
return result; return result;
} }
@ -55,9 +55,9 @@ DN_API bool DN_OS_MemCommit(void *ptr, DN_USize size, DN_U32 page_flags)
return false; return false;
unsigned long os_page_flags = DN_OS_MemConvertPageToOSFlags_(page_flags); unsigned long os_page_flags = DN_OS_MemConvertPageToOSFlags_(page_flags);
result = VirtualAlloc(ptr, size, MEM_COMMIT, os_page_flags) != nullptr; result = VirtualAlloc(ptr, size, MEM_COMMIT, os_page_flags) != nullptr;
DN_Assert(g_dn_); DN_Core *dn = DN_Get();
DN_AtomicAddU64(&g_dn_->os.vmem_allocs_total, 1); DN_AtomicAddU64(&dn->os.vmem_allocs_total, 1);
DN_AtomicAddU64(&g_dn_->os.vmem_allocs_frame, 1); DN_AtomicAddU64(&dn->os.vmem_allocs_frame, 1);
return result; return result;
} }
@ -83,10 +83,9 @@ DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags)
if (!ptr || size == 0) if (!ptr || size == 0)
return 0; return 0;
static DN_Str8 const ALIGNMENT_ERROR_MSG = static DN_Str8 const ALIGNMENT_ERROR_MSG = DN_Str8Lit("Page protection requires pointers to be page aligned because we can only guard memory at a multiple of the page boundary.");
DN_Str8Lit("Page protection requires pointers to be page aligned because we can only guard memory at a multiple of the page boundary."); DN_AssertF(DN_IsPowerOfTwoAligned(DN_Cast(uintptr_t) ptr, DN_Get()->os.page_size), "%s", ALIGNMENT_ERROR_MSG.data);
DN_AssertF(DN_IsPowerOfTwoAligned(DN_Cast(uintptr_t) ptr, g_dn_->os.page_size), "%s", ALIGNMENT_ERROR_MSG.data); DN_AssertF(DN_IsPowerOfTwoAligned(size, DN_Get()->os.page_size), "%s", ALIGNMENT_ERROR_MSG.data);
DN_AssertF(DN_IsPowerOfTwoAligned(size, g_dn_->os.page_size), "%s", ALIGNMENT_ERROR_MSG.data);
unsigned long os_page_flags = DN_OS_MemConvertPageToOSFlags_(page_flags); unsigned long os_page_flags = DN_OS_MemConvertPageToOSFlags_(page_flags);
unsigned long prev_flags = 0; unsigned long prev_flags = 0;
@ -100,13 +99,13 @@ DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags)
DN_API void *DN_OS_MemAlloc(DN_USize size, DN_ZMem z_mem) DN_API void *DN_OS_MemAlloc(DN_USize size, DN_ZMem z_mem)
{ {
DN_RawAssert(g_dn_->init_flags & DN_InitFlags_OS && "DN must be initialised with the OS flag"); DN_Core *dn = DN_Get();
DN_RawAssert(dn->init_flags & DN_InitFlags_OS && "DN must be initialised with the OS flag");
DN_U32 flags = z_mem == DN_ZMem_Yes ? HEAP_ZERO_MEMORY : 0; DN_U32 flags = z_mem == DN_ZMem_Yes ? HEAP_ZERO_MEMORY : 0;
DN_Assert(size <= DN_Cast(DWORD)(-1)); DN_Assert(size <= DN_Cast(DWORD)(-1));
void *result = HeapAlloc(GetProcessHeap(), flags, DN_Cast(DWORD) size); void *result = HeapAlloc(GetProcessHeap(), flags, DN_Cast(DWORD) size);
DN_Assert(g_dn_); DN_AtomicAddU64(&dn->os.mem_allocs_total, 1);
DN_AtomicAddU64(&g_dn_->os.mem_allocs_total, 1); DN_AtomicAddU64(&dn->os.mem_allocs_frame, 1);
DN_AtomicAddU64(&g_dn_->os.mem_allocs_frame, 1);
return result; return result;
} }
@ -199,8 +198,7 @@ DN_API DN_U64 DN_OS_DateLocalUnixTimeSFromUnixTimeS(DN_U64 unix_ts_s)
DN_API void DN_OS_GenBytesSecure(void *buffer, DN_U32 size) DN_API void DN_OS_GenBytesSecure(void *buffer, DN_U32 size)
{ {
DN_Assert(g_dn_); DN_OSW32Core *w32 = DN_Cast(DN_OSW32Core *) DN_Get()->os.platform_context;
DN_OSW32Core *w32 = DN_Cast(DN_OSW32Core *) g_dn_->os.platform_context;
DN_Assert(w32->bcrypt_init_success); DN_Assert(w32->bcrypt_init_success);
long gen_status = BCryptGenRandom(w32->bcrypt_rng_handle, DN_Cast(unsigned char *) buffer, size, 0 /*flags*/); long gen_status = BCryptGenRandom(w32->bcrypt_rng_handle, DN_Cast(unsigned char *) buffer, size, 0 /*flags*/);
@ -262,8 +260,7 @@ DN_API void DN_OS_SleepMs(DN_UInt milliseconds)
DN_API DN_U64 DN_OS_PerfCounterFrequency() DN_API DN_U64 DN_OS_PerfCounterFrequency()
{ {
DN_Assert(g_dn_); DN_OSW32Core *w32 = DN_Cast(DN_OSW32Core *) DN_Get()->os.platform_context;
DN_OSW32Core *w32 = DN_Cast(DN_OSW32Core *) g_dn_->os.platform_context;
DN_Assert(w32->qpc_frequency.QuadPart); DN_Assert(w32->qpc_frequency.QuadPart);
DN_U64 result = w32->qpc_frequency.QuadPart; DN_U64 result = w32->qpc_frequency.QuadPart;
return result; return result;
@ -1008,8 +1005,9 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, DN_OSExecArgs
DN_API DN_OSW32Core *DN_OS_W32GetCore() DN_API DN_OSW32Core *DN_OS_W32GetCore()
{ {
DN_Assert(g_dn_ && g_dn_->os.platform_context); DN_Core *dn = DN_Get();
DN_OSW32Core *result = DN_Cast(DN_OSW32Core *)g_dn_->os.platform_context; DN_Assert(dn && dn->os_init);
DN_OSW32Core *result = DN_Cast(DN_OSW32Core *)dn->os.platform_context;
return result; return result;
} }
@ -1039,7 +1037,7 @@ static DN_OSW32SyncPrimitive *DN_OS_W32AllocSyncPrimitive_()
w32->sync_primitive_free_list = w32->sync_primitive_free_list->next; w32->sync_primitive_free_list = w32->sync_primitive_free_list->next;
result->next = nullptr; result->next = nullptr;
} else { } else {
DN_OSCore *os = &g_dn_->os; DN_OSCore *os = &DN_Get()->os;
result = DN_ArenaNew(&os->arena, DN_OSW32SyncPrimitive, DN_ZMem_Yes); result = DN_ArenaNew(&os->arena, DN_OSW32SyncPrimitive, DN_ZMem_Yes);
} }
} }

View File

@ -22,7 +22,7 @@ DN_Core *g_dn_;
DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args) DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args)
{ {
g_dn_ = dn; DN_Set(dn);
dn->init_flags = flags; dn->init_flags = flags;
if (DN_BitIsSet(flags, DN_InitFlags_OS)) { if (DN_BitIsSet(flags, DN_InitFlags_OS)) {
@ -216,6 +216,17 @@ DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args)
DN_LogDebugF("%.*s", DN_Cast(int)buf_size, buf); DN_LogDebugF("%.*s", DN_Cast(int)buf_size, buf);
} }
DN_API void DN_Set(DN_Core *dn)
{
g_dn_ = dn;
}
DN_API DN_Core *DN_Get()
{
DN_Core *result = g_dn_;
return result;
}
DN_API void DN_BeginFrame() DN_API void DN_BeginFrame()
{ {
#if DN_H_WITH_OS #if DN_H_WITH_OS

View File

@ -134,10 +134,10 @@ struct DN_Core
#endif #endif
}; };
extern DN_Core *g_dn_; DN_API void DN_Init (DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args);
DN_API void DN_Set (DN_Core *dn);
DN_API void DN_Init (DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args); DN_API DN_Core *DN_Get ();
DN_API void DN_BeginFrame(); DN_API void DN_BeginFrame();
#if DN_H_WITH_HELPERS #if DN_H_WITH_HELPERS
#include "Extra/dn_helpers.h" #include "Extra/dn_helpers.h"

View File

@ -1,10 +1,20 @@
// raddbg 0.9.25 project file // raddbg 0.9.25 project file
recent_file: path: "C:/Home/Cloud/Code/DN/Source/Extra/dn_net_curl.cpp"
recent_file: path: "C:/Home/Cloud/Code/DN/Source/Extra/dn_tests.cpp"
recent_file: path: "C:/Home/Cloud/Code/DN/Source/Extra/dn_tests_main.cpp"
recent_file: path: "C:/Home/Cloud/Code/DN/Source/Standalone/dn_utest.h"
recent_file: path: "C:/Home/Cloud/Code/DN/Source/OS/dn_os_w32.cpp"
recent_file: path: "D:/a/_work/1/s/src/vctools/asan/llvm/compiler-rt/lib/asan/asan_thread.cpp"
recent_file: path: "C:/Home/Cloud/Code/DN/Source/Base/dn_base.cpp"
recent_file: path: "D:/a/_work/1/s/src/vctools/asan/llvm/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp"
recent_file: path: "D:/a/_work/1/s/src/vctools/asan/llvm/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp"
recent_file: path: "D:/a/_work/1/s/src/vctools/asan/llvm/compiler-rt/lib/asan/asan_rtl.cpp"
recent_file: path: "Source/OS/dn_os_w32.cpp" recent_file: path: "Source/OS/dn_os_w32.cpp"
target: target:
{ {
executable: "Build/dn_unit_tests_msvc.exe" executable: "Build/dn_unit_tests_msvc.exe"
working_directory: "Build/" working_directory: Build
enabled: 1 enabled: 1
} }
debug_info: debug_info:
@ -17,3 +27,13 @@ debug_info:
path: "C:/Home/Cloud/Dev/Win/msvc/msvc_host_x64_target_x64/14.41.17.11/VC/Tools/MSVC/14.41.34120/bin/Hostx64/x64/clang_rt.asan_dynamic-x86_64.pdb" path: "C:/Home/Cloud/Dev/Win/msvc/msvc_host_x64_target_x64/14.41.17.11/VC/Tools/MSVC/14.41.34120/bin/Hostx64/x64/clang_rt.asan_dynamic-x86_64.pdb"
timestamp: 66163731918117 timestamp: 66163731918117
} }
debug_info:
{
path: "C:/Home/Cloud/Code/DN/Build/dn_unit_tests_msvc.pdb"
timestamp: 66208715842393
}
debug_info:
{
path: "C:/Home/Sync/PC/W32/Apps/msvc/msvc_host_x64_target_x64/14.41.17.11/VC/Tools/MSVC/14.41.34120/bin/Hostx64/x64/clang_rt.asan_dynamic-x86_64.pdb"
timestamp: 66163731918117
}