From 2659f0316f13ad8ce899dcb2a798d1d1de9e992d Mon Sep 17 00:00:00 2001 From: doylet Date: Thu, 18 Jun 2026 16:41:12 +1000 Subject: [PATCH] Update to latest DN library --- Single-Header/dn_single_header.cpp | 129 ++++++++++++----- Single-Header/dn_single_header.h | 224 +++++++++++++++++++++++++---- Source/Base/dn_base.cpp | 10 +- Source/Base/dn_base.h | 142 +++++++++++++++--- Source/Base/dn_base_containers.cpp | 15 ++ Source/Extra/dn_async.cpp | 2 +- Source/Extra/dn_bin_pack.cpp | 2 +- Source/Extra/dn_net.cpp | 2 - Source/Extra/dn_net_curl.cpp | 30 ++-- Source/Extra/dn_net_emscripten.cpp | 8 +- Source/Extra/dn_tests.cpp | 14 +- Source/Extra/dn_tests_main.cpp | 2 +- Source/OS/dn_os.cpp | 46 +++++- Source/OS/dn_os.h | 78 +++++++++- Source/OS/dn_os_posix.cpp | 33 ++--- Source/OS/dn_os_w32.cpp | 3 +- Source/dn.h | 2 +- 17 files changed, 602 insertions(+), 140 deletions(-) diff --git a/Single-Header/dn_single_header.cpp b/Single-Header/dn_single_header.cpp index 7e50594..7002f7e 100644 --- a/Single-Header/dn_single_header.cpp +++ b/Single-Header/dn_single_header.cpp @@ -1,4 +1,4 @@ -// Generated by the DN single header generator 2026-06-01 21:40:06 +// Generated by the DN single header generator 2026-06-18 16:40:52 // DN: Single header generator commented out => #if defined(_CLANGD) // #define DN_H_WITH_OS 1 @@ -4368,10 +4368,11 @@ DN_API DN_U8x32 DN_BytesFromHex64Ptr(char const *hex, DN_USize hex_count) return result; } -DN_API DN_HexU64Str8 DN_HexFromU64(DN_U64 value, DN_HexFromU64Type type) +DN_API DN_HexU64 DN_HexFromU64(DN_U64 value, DN_HexFromU64Type type) { - DN_HexU64Str8 result = {}; - DN_HexFromPtrBytes(&value, sizeof(value), result.data, sizeof(result.data), DN_TrimLeadingZero_No); + DN_HexU64 result = {}; + DN_USize size = DN_HexFromPtrBytes(&value, sizeof(value), result.data, sizeof(result.data), DN_TrimLeadingZero_No); + result.size = DN_SaturateCastUSizeToU8(size); if (type == DN_HexFromU64Type_Uppercase) { for (DN_USize index = 0; index < result.size; index++) result.data[index] = DN_CharToUpper(result.data[index]); @@ -5544,7 +5545,8 @@ DN_API void DN_LogPrint(DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags { DN_Core *dn = DN_Get(); if (type.is_u32_enum) { - if (type.u32 < dn->log_level_to_show_from) + DN_Assert(dn->log_level_to_show_from >= 0); + if (type.u32 < DN_Cast(DN_U32)dn->log_level_to_show_from) return; } @@ -7429,6 +7431,7 @@ DN_API void *DN_ArrayPopBack(void *data, DN_USize *size, DN_USize elem_size, DN_ DN_API DN_ArrayEraseResult DN_ArrayEraseRange(void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase) { DN_ArrayEraseResult result = {}; + result.it_index = begin_index; if (!data || !size || *size == 0 || count == 0) return result; @@ -7485,6 +7488,13 @@ DN_API void *DN_ArrayMakeArray(void *data, DN_USize *size, DN_USize max, DN_USiz return result; } +DN_API void *DN_ArrayMakeArrayAssert(void *data, DN_USize *size, DN_USize max, DN_USize elem_size, DN_USize make_count, DN_ZMem z_mem, DN_CallSite call_site) +{ + void *result = DN_ArrayMakeArray(data, size, max, elem_size, make_count, z_mem); + DN_AssertArgsF(result, call_site, "array=%p size=%zu max=%zu", data, *size, max); + return result; +} + DN_API void *DN_ArrayAddArray(void *data, DN_USize *size, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add) { void *result = DN_ArrayMakeArray(data, size, max, elem_size, elems_count, DN_ZMem_No); @@ -7501,6 +7511,13 @@ DN_API void *DN_ArrayAddArray(void *data, DN_USize *size, DN_USize max, DN_USize return result; } +DN_API void *DN_ArrayAddArrayAssert(void *data, DN_USize *size, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add, DN_CallSite call_site) +{ + void *result = DN_ArrayAddArray(data, size, max, elem_size, elems, elems_count, add); + DN_AssertArgsF(result, call_site, "array=%p size=%zu max=%zu", data, *size, max); + return result; +} + DN_API bool DN_ArrayResizeFromArena(void **data, DN_USize *size, DN_USize *max, DN_USize elem_size, DN_Pool *pool, DN_USize new_max) { bool result = true; @@ -9000,8 +9017,8 @@ DN_API DN_OSExecResult DN_OS_ExecOrAbort(DN_Str8Slice cmd_line, DN_OSExecArgs *a // NOTE: DN_OSThread static void DN_OS_ThreadExecute_(void *user_context) { - DN_OSThread *thread = DN_Cast(DN_OSThread *) user_context; - DN_TCInitFromMemFuncs(&thread->context, thread->thread_id, DN_TCInitArgsDefault(), DN_MemFuncsDefault()); + DN_OSThread *thread = DN_Cast(DN_OSThread *) user_context; + DN_TCInitFromMemFuncs(&thread->context, thread->thread_id, thread->tc_init_args, DN_MemFuncsDefault()); DN_TCEquip(&thread->context); if (thread->is_lane_set) { DN_OS_TCThreadLaneEquip(thread->lane); @@ -9063,7 +9080,7 @@ DN_API void DN_OS_ThreadLaneSync(DN_OSThreadLane *lane, void **ptr_to_share) DN_OS_BarrierWait(&lane->barrier); // NOTE: Ensure the reading lanes have completed the read } -DN_API DN_V2USize DN_OS_ThreadLaneRange(DN_OSThreadLane *lane, DN_USize values_count) +DN_API DN_V2USize DN_OS_ThreadLaneRange(DN_OSThreadLane const *lane, DN_USize values_count) { DN_USize values_per_thread = values_count / lane->count; DN_USize rem_values = values_count % lane->count; @@ -9084,6 +9101,44 @@ DN_API DN_V2USize DN_OS_ThreadLaneRange(DN_OSThreadLane *lane, DN_USize values_c return result; } +DN_API DN_OSThreadLaneway DN_OS_ThreadLanewayFromArgs(DN_OSThread* threads, DN_USize threads_count, DN_UPtr* shared_mem) +{ + DN_OSThreadLaneway result = {}; + result.threads = threads; + result.threads_count = threads_count; + result.shared_mem = shared_mem; + result.barrier = DN_OS_BarrierInit(DN_Cast(DN_U32) result.threads_count); + return result; +} + +DN_API DN_OSThreadLaneway DN_OS_ThreadLanewayFromArena(DN_USize threads_count, DN_Arena* arena) +{ + DN_U64 mem_p = DN_MemListPos(arena->mem); + DN_OSThreadLaneway result = {}; + DN_OSThread* threads = DN_ArenaNewArray(arena, DN_OSThread, threads_count, DN_ZMem_No); + DN_UPtr* shared_mem = DN_ArenaNewZ(arena, DN_UPtr); + if (threads && shared_mem) + result = DN_OS_ThreadLanewayFromArgs(threads, threads_count, shared_mem); + else + DN_MemListPopTo(arena->mem, mem_p); + return result; +} + +DN_API void DN_OS_ThreadLanewayDispatch(DN_OSThreadLaneway *laneway, DN_OSThreadFunc *entry_point, DN_TCInitArgs tc_init_args, void *user_context) +{ + for (DN_ForItSize(it, DN_OSThread, laneway->threads, laneway->threads_count)) { + DN_OSThreadLane lane = DN_OS_ThreadLaneInit(it.index, laneway->threads_count, laneway->barrier, laneway->shared_mem); + DN_OS_ThreadInit(it.data, entry_point, &lane, tc_init_args, user_context); + } +} + +DN_API void DN_OS_ThreadLanewayJoin(DN_OSThreadLaneway *laneway, DN_TCDeinitArenas deinit_arenas) +{ + for (DN_ForItSize(it, DN_OSThread, laneway->threads, laneway->threads_count)) + DN_OS_ThreadJoin(it.data, deinit_arenas); + DN_OS_BarrierDeinit(&laneway->barrier); +} + DN_API DN_OSThreadLane *DN_OS_TCThreadLane() { DN_TCCore *tc = DN_TCGet(); @@ -9531,7 +9586,7 @@ DN_API DN_StackTrace DN_StackTraceFromAllocator(DN_Allocator allocator, DN_U16 l DN_Memcpy(result.base_addr, raw_frames, raw_frames_count * sizeof(raw_frames[0])); #else (void)limit; - (void)arena; + (void)allocator; #endif return result; } @@ -9940,7 +9995,7 @@ DN_API bool DN_OS_SetEnvVar(DN_Str8 name, DN_Str8 value) DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path) { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); DN_OSDiskSpace result = {}; DN_Str8 path_z_terminated = DN_Str8FromStr8Arena(path, &scratch.arena); struct statvfs info = {}; @@ -10099,7 +10154,7 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink result = (bytes_written == stat_existing.st_size); if (!result) { int error_code = errno; - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); DN_Str8 file_size_str8 = DN_Str8FromByteCount(scratch.arena, stat_existing.st_size, DN_ByteCountType_Auto); DN_Str8 bytes_written_str8 = DN_Str8FromByteCount(scratch.arena, bytes_written, DN_ByteCountType_Auto); DN_rrSinkAppendF(error, @@ -10229,8 +10284,8 @@ DN_API DN_OSFileRead DN_OS_FileRead(DN_OSFile *file, void *buffer, DN_USize size result.bytes_read = fread(buffer, 1, size, DN_Cast(FILE *) file->handle); if (feof(DN_Cast(FILE*)file->handle)) { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); - DN_Str8x32 buffer_size_str8 = DN_ByteCountStr8x32(size); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); + DN_Str8x32 buffer_size_str8 = DN_Str8x32FromByteCountU64Auto(size); DN_ErrSinkAppendF(err, 1, "Failed to read %S from file", buffer_size_str8); DN_TCScratchEnd(&scratch); return result; @@ -10248,8 +10303,8 @@ DN_API bool DN_OS_FileWritePtr(DN_OSFile *file, void const *buffer, DN_USize siz fwrite(buffer, DN_Cast(DN_USize) size, 1 /*count*/, DN_Cast(FILE *) file->handle) == 1 /*count*/; if (!result) { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); - DN_Str8x32 buffer_size_str8 = DN_ByteCountStr8x32(size); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); + DN_Str8x32 buffer_size_str8 = DN_Str8x32FromByteCountU64Auto(size); DN_ErrSinkAppendF(err, 1, "Failed to write buffer (%s) to file handle", DN_Str8PrintFmt(buffer_size_str8)); DN_TCScratchEnd(&scratch); } @@ -10339,7 +10394,7 @@ DN_API bool DN_OS_PathIsDir(DN_Str8 path) DN_API bool DN_OS_PathMakeDir(DN_Str8 path) { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); bool result = true; // TODO(doyle): Implement this without using the path indexes, it's not @@ -10505,7 +10560,7 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, // NOTE: Read the data from the read end of the pipe if (result.os_error_code == 0) { - DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1); + DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1); if (arena && handle.stdout_read) { char buffer[4096]; DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena); @@ -10517,7 +10572,7 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, DN_Str8BuilderAppendF(&builder, "%.*s", bytes_read, buffer); } - result.stdout_text = DN_Str8BuilderBuild(&builder, arena); + result.stdout_text = DN_Str8FromStr8BuilderArena(&builder, arena); } if (arena && handle.stderr_read) { @@ -10531,7 +10586,7 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, DN_Str8BuilderAppendF(&builder, "%.*s", bytes_read, buffer); } - result.stderr_text = DN_Str8BuilderBuild(&builder, arena); + result.stderr_text = DN_Str8FromStr8BuilderArena(&builder, arena); } DN_TCScratchEnd(&scratch); } @@ -10554,7 +10609,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, if (cmd_line.count == 0) return result; - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); DN_DEFER { DN_TCScratchEnd(&scratch); }; DN_Str8 cmd_rendered = DN_Str8SliceRender(cmd_line, DN_Str8Lit(" "), &scratch.arena); int stdout_pipe[DN_OSPipeType__Count] = {}; @@ -10998,7 +11053,7 @@ static void *DN_OS_ThreadFunc_(void *user_context) return nullptr; } -DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, void *user_context) +DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, DN_TCInitArgs tc_init_args, void *user_context) { bool result = false; if (!thread) @@ -11008,6 +11063,7 @@ DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSTh thread->user_context = user_context; thread->init_semaphore = DN_OS_SemaphoreInit(0 /*initial_count*/); thread->lane = *lane; + thread->tc_init_args = tc_init_args; // TODO(doyle): Check if semaphore is valid // NOTE: pthread_t is essentially the thread ID. In Windows, the handle and @@ -11082,7 +11138,7 @@ DN_API void DN_OS_PosixThreadSetName(DN_Str8 name) #if defined(DN_PLATFORM_EMSCRIPTEN) (void)name; #else - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); DN_Str8 copy = DN_Str8FromStr8Arena(name, &scratch.arena); pthread_t thread = pthread_self(); pthread_setname_np(thread, (char *)copy.data); @@ -11106,7 +11162,7 @@ DN_API DN_OSPosixProcSelfStatus DN_OS_PosixProcSelfStatus() DN_OSFile file = DN_OS_FileOpen(DN_Str8Lit("/proc/self/status"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_Read, nullptr); if (!file.error) { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); char buf[256]; DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena); for (;;) { @@ -11120,7 +11176,7 @@ DN_API DN_OSPosixProcSelfStatus DN_OS_PosixProcSelfStatus() DN_Str8 const PID = DN_Str8Lit("Pid:"); DN_Str8 const VM_PEAK = DN_Str8Lit("VmPeak:"); DN_Str8 const VM_SIZE = DN_Str8Lit("VmSize:"); - DN_Str8 status_buf = DN_Str8BuilderBuild(&builder, &scratch.arena); + DN_Str8 status_buf = DN_Str8FromStr8BuilderArena(&builder, &scratch.arena); DN_Str8SplitResult lines = DN_Str8SplitArena(status_buf, DN_Str8Lit("\n"), DN_Str8SplitFlags_ExcludeEmptyStrings, &scratch.arena); for (DN_ForItSize(line_it, DN_Str8, lines.data, lines.count)) { @@ -11247,7 +11303,7 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response, response->builder.arena = response->scratch_arena.mem ? &response->scratch_arena : &response->tmp_arena; DN_Arena *scratch = &response->scratch_arena; - DN_TCScratch scratch_ = DN_TCScratchBegin(&arena, 1); + DN_TCScratch scratch_ = DN_TCScratchBeginArena(&arena, 1); DN_DEFER { DN_TCScratchEnd(&scratch_); }; if (!scratch) scratch = &scratch_.arena; @@ -12549,7 +12605,7 @@ static DWORD __stdcall DN_OS_ThreadFunc_(void *user_context) return 0; } -DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, void *user_context) +DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, DN_TCInitArgs tc_init_args, void *user_context) { bool result = false; if (!thread) @@ -12558,6 +12614,7 @@ DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSTh thread->func = func; thread->user_context = user_context; thread->init_semaphore = DN_OS_SemaphoreInit(0 /*initial_count*/); + thread->tc_init_args = tc_init_args; if (lane) { thread->is_lane_set = true; thread->lane = *lane; @@ -13620,7 +13677,7 @@ DN_API void DN_ASYNC_Init(DN_ASYNCCore *async, char *base, DN_USize base_size, D async->threads = threads; for (DN_ForIndexU(index, async->thread_count)) { DN_OSThread *thread = async->threads + index; - DN_OS_ThreadInit(thread, DN_ASYNC_ThreadEntryPoint_, nullptr, async); + DN_OS_ThreadInit(thread, DN_ASYNC_ThreadEntryPoint_, /*lane=*/ nullptr, DN_TCInitArgsDefault(), async); } } @@ -13822,8 +13879,6 @@ void DN_NET_EndFinishedRequest(DN_NETRequest *request) { // NOTE: Deallocate the memory used in the request and reset the string builder DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes); - // NOTE: Check that the request is completely detached - DN_Assert(request->next == nullptr); } #endif @@ -15053,7 +15108,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 5, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 2); - DN_UT_AssertF(&result, erase.it_index == 2, "erase.it_index=%zu", erase.it_index); + DN_UT_Assert(&result, erase.it_index == 3); DN_UT_Assert(&result, size == 8); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -15064,7 +15119,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 3); - DN_UT_Assert(&result, erase.it_index == 2); + DN_UT_Assert(&result, erase.it_index == 3); DN_UT_Assert(&result, size == 7); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -15075,7 +15130,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -1, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 3, 4, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 1); - DN_UT_Assert(&result, erase.it_index == 4); + DN_UT_Assert(&result, erase.it_index == 5); DN_UT_Assert(&result, size == 9); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -15086,7 +15141,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Unstable); int expected[] = {0, 1, 2, 8, 9, 5, 6, 7}; DN_UT_Assert(&result, erase.items_erased == 2); - DN_UT_Assert(&result, erase.it_index == 2); + DN_UT_Assert(&result, erase.it_index == 3); DN_UT_Assert(&result, size == 8); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -15097,7 +15152,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Unstable); int expected[] = {0, 1, 2, 7, 8, 9, 6}; DN_UT_Assert(&result, erase.items_erased == 3); - DN_UT_Assert(&result, erase.it_index == 2); + DN_UT_Assert(&result, erase.it_index == 3); DN_UT_Assert(&result, size == 7); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -15119,7 +15174,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 9, 2, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; DN_UT_Assert(&result, erase.items_erased == 1); - DN_UT_Assert(&result, erase.it_index == 8); + DN_UT_Assert(&result, erase.it_index == 9); DN_UT_Assert(&result, size == 9); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -15165,7 +15220,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 15, 2, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 0); - DN_UT_Assert(&result, erase.it_index == 9); + DN_UT_Assert(&result, erase.it_index == 10); DN_UT_Assert(&result, size == 10); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -18471,7 +18526,7 @@ DN_API void DN_BinPackCBuffer(DN_BinPack *pack, DN_BinPackMode mode, char *ptr, DN_API DN_Str8 DN_BinPackBuild(DN_BinPack const *pack, DN_Arena *arena) { - DN_Str8 result = DN_Str8FromStr8BuilderArena(&pack->writer, arena); + DN_Str8 result = DN_Str8BuilderBuild(&pack->writer, arena); return result; } #define DN_CSV_CPP diff --git a/Single-Header/dn_single_header.h b/Single-Header/dn_single_header.h index 2c87e84..187de8e 100644 --- a/Single-Header/dn_single_header.h +++ b/Single-Header/dn_single_header.h @@ -1,4 +1,4 @@ -// Generated by the DN single header generator 2026-06-01 21:40:06 +// Generated by the DN single header generator 2026-06-18 16:40:52 #if !defined(DN_H) #define DN_H @@ -353,33 +353,30 @@ #define DN_RawAssert(...) #define DN_Assert(...) #define DN_AssertOnce(...) + #define DN_AssertArgsF(...) #define DN_AssertF(...) #define DN_AssertFOnce(...) #else #define DN_RawAssert(expr) do { if (!(expr)) DN_DebugBreak; } while (0) - - #define DN_AssertF(expr, fmt, ...) \ + #define DN_AssertArgsF(expr, call_site, fmt, ...) \ do { \ if (!(expr)) { \ - DN_Str8 stack_trace_ = DN_Str8FromStackTraceNowHeap(128 /*limit*/, 3 /*skip*/); \ - DN_LogErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ - DN_Str8PrintFmt(stack_trace_), \ - ##__VA_ARGS__); \ - DN_DebugBreak; \ - } \ + DN_Str8 stack_trace_ = DN_Str8FromStackTraceNowHeap(128 /*limit*/, 3 /*skip*/); \ + DN_LogPrint(DN_LogTypeParamFromType(DN_LogType_Error), \ + call_site, \ + DN_LogFlags_Nil, \ + "Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ + DN_Str8PrintFmt(stack_trace_), \ + ##__VA_ARGS__); \ + DN_DebugBreak; \ + } \ } while (0) - #define DN_AssertFOnce(expr, fmt, ...) \ - do { \ - static bool once = true; \ - if (!(expr) && once) { \ - once = false; \ - DN_Str8 stack_trace_ = DN_Str8FromStackTraceNowHeap(128 /*limit*/, 3 /*skip*/); \ - DN_LogErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ - DN_Str8PrintFmt(stack_trace_), \ - ##__VA_ARGS__); \ - DN_DebugBreak; \ - } \ + #define DN_AssertF(expr, fmt, ...) DN_AssertArgsF(expr, DN_CALL_SITE, fmt, ## __VA_ARGS__) + #define DN_AssertFOnce(expr, fmt, ...) \ + do { \ + for (static bool once_ = true; !(expr) && once_; once_ = false) \ + DN_AssertF(expr, fmt, ## __VA_ARGS__); \ } while (0) #define DN_Assert(expr) DN_AssertF((expr), "") @@ -786,7 +783,7 @@ struct DN_Hex32 { char data[32 + 1]; DN_USize size; }; struct DN_Hex64 { char data[64 + 1]; DN_USize size; }; struct DN_Hex128 { char data[128 + 1]; DN_USize size; }; -struct DN_HexU64Str8 +struct DN_HexU64 { char data[(sizeof(DN_U64) * 2) + 1 /*null-terminator*/]; DN_U8 size; @@ -1711,7 +1708,7 @@ struct DN_ArrayEraseResult // // for (DN_USize index = 0; index < array.size; index++) { // if (erase) - // index = DN_ArrayEraseRange(&array, index, -3, DN_ArrayErase_Unstable).it_index; + // index = DN_FArray_EraseRange(&array, index, -3, DN_ArrayErase_Unstable); // } DN_USize it_index; DN_USize items_erased; // The number of items erased @@ -3730,6 +3727,12 @@ DN_MSVC_WARNING_POP DN_API bool DN_MemStartsWith (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); DN_API bool DN_MemEqUnsafe (void const *lhs, void const *rhs, DN_USize size); +#if defined(__cplusplus) +template T* DN_TMemCopyObj (T *dest, T const *src, DN_USize count); +#define DN_MemCopyObj(dest, src, count) DN_TMemCopyObj(dest, src, count) +#else +#define DN_MemCopyObj(dest, src, count) DN_Memcpy(dest, src, sizeof(*src) * count) +#endif DN_API DN_U64 DN_AtomicSetValue64 (DN_U64 volatile *target, DN_U64 value); DN_API DN_U32 DN_AtomicSetValue32 (DN_U32 volatile *target, DN_U32 value); @@ -4207,7 +4210,7 @@ DN_API DN_Str8 DN_BytesFromHexPtrPool DN_API DN_U8x16 DN_BytesFromHex32Ptr (char const *hex, DN_USize hex_count); DN_API DN_U8x32 DN_BytesFromHex64Ptr (char const *hex, DN_USize hex_count); -DN_API DN_HexU64Str8 DN_HexFromU64 (DN_U64 value, DN_HexFromU64Type type); +DN_API DN_HexU64 DN_HexFromU64 (DN_U64 value, DN_HexFromU64Type type); DN_API DN_USize DN_HexFromPtrBytes (void const *bytes, DN_USize bytes_count, void *hex, DN_USize hex_count, DN_TrimLeadingZero trim_leading_z); DN_API DN_Str8 DN_HexFromPtrBytesArena (void const *bytes, DN_USize bytes_count, DN_Arena *arena, DN_TrimLeadingZero trim_leading_z); DN_API DN_USize DN_HexFromStr8Bytes (DN_Str8 bytes, void *hex, DN_USize hex_count, DN_TrimLeadingZero trim_leading_z); @@ -4841,6 +4844,8 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 if ((head)) { \ (ptr)->next = (head)->next; \ (head)->next = (ptr); \ + if ((ptr)->next) \ + (ptr)->next->prev = (ptr); \ } else { \ (head) = (ptr); \ } \ @@ -4856,6 +4861,8 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 if ((head)) { \ (ptr)->prev = (head)->prev; \ (head)->prev = (ptr); \ + if ((ptr)->prev) \ + (ptr)->prev->next = (ptr); \ } else { \ (head) = (ptr); \ } \ @@ -4912,16 +4919,29 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 #define DN_PArrayGrowFromArena(ptr, size, ptr_max, arena, new_max) DN_TArrayGrowFromArena(&(ptr), size, ptr_max, arena, new_max) #define DN_PArrayGrowIfNeededFromPool(ptr, size, ptr_max, pool, add_count) DN_TArrayGrowIfNeededFromPool(ptr, size, ptr_max, pool, add_count) #define DN_PArrayGrowIfNeededFromArena(ptr, size, ptr_max, arena, add_count) DN_TArrayGrowIfNeededFromArena(ptr, size, ptr_max, arena, add_count) + #define DN_PArrayMakeArray(ptr, ptr_size, max, count, z_mem) DN_TArrayMakeArray(ptr, ptr_size, max, count, z_mem) #define DN_PArrayMakeArrayZ(ptr, ptr_size, max, count) DN_TArrayMakeArray(ptr, ptr_size, max, count, DN_ZMem_Yes) + #define DN_PArrayMakeArrayNoZ(ptr, ptr_size, max, count) DN_TArrayMakeArray(ptr, ptr_size, max, count, DN_ZMem_No) + #define DN_PArrayMakeArrayAssert(ptr, ptr_size, max, count, z_mem) DN_TArrayMakeArrayAssert(ptr, ptr_size, max, count, z_mem, DN_CALL_SITE) + #define DN_PArrayMakeArrayAssertZ(ptr, ptr_size, max, count) DN_TArrayMakeArrayAssert(ptr, ptr_size, max, count, DN_ZMem_Yes, DN_CALL_SITE) + #define DN_PArrayMakeArrayAssertNoZ(ptr, ptr_size, max, count) DN_TArrayMakeArrayAssert(ptr, ptr_size, max, count, DN_ZMem_No, DN_CALL_SITE) + #define DN_PArrayMake(ptr, ptr_size, max, z_mem) DN_TArrayMakeArray(ptr, ptr_size, max, 1, z_mem) #define DN_PArrayMakeZ(ptr, ptr_size, max) DN_TArrayMakeArray(ptr, ptr_size, max, 1, DN_ZMem_Yes) + #define DN_PArrayMakeNoZ(ptr, ptr_size, max) DN_TArrayMakeArray(ptr, ptr_size, max, 1, DN_ZMem_No) + #define DN_PArrayMakeAssert(ptr, ptr_size, max, z_mem) DN_TArrayMakeArrayAssert(ptr, ptr_size, max, 1, z_mem, DN_CALL_SITE) + #define DN_PArrayMakeAssertZ(ptr, ptr_size, max) DN_TArrayMakeArrayAssert(ptr, ptr_size, max, 1, DN_ZMem_Yes, DN_CALL_SITE) + #define DN_PArrayMakeAssertNoZ(ptr, ptr_size, max) DN_TArrayMakeArrayAssert(ptr, ptr_size, max, 1, DN_ZMem_No, DN_CALL_SITE) + #define DN_PArrayAddArray(ptr, ptr_size, max, items, count, add) DN_TArrayAddArray(ptr, ptr_size, max, items, count, add) #define DN_PArrayAdd(ptr, ptr_size, max, item, add) DN_TArrayAddArray(ptr, ptr_size, max, &item, 1, add) #define DN_PArrayAppendArray(ptr, ptr_size, max, items, count) DN_TArrayAddArray(ptr, ptr_size, max, items, count, DN_ArrayAdd_Append) #define DN_PArrayAppend(ptr, ptr_size, max, item) DN_TArrayAddArray(ptr, ptr_size, max, &item, 1, DN_ArrayAdd_Append) + #define DN_PArrayAppendAssert(ptr, ptr_size, max, item) DN_TArrayAddArrayAssert(ptr, ptr_size, max, &item, 1, DN_ArrayAdd_Append, DN_CALL_SITE) #define DN_PArrayPrependArray(ptr, ptr_size, max, items, count) DN_TArrayAddArray(ptr, ptr_size, max, items, count, DN_ArrayAdd_Prepend) #define DN_PArrayPrepend(ptr, ptr_size, max, item) DN_TArrayAddArray(ptr, ptr_size, max, &item, 1, DN_ArrayAdd_Prepend) + #define DN_PArrayEraseRange(ptr, ptr_size, begin_index, count, erase) DN_TArrayEraseRange(ptr, ptr_size, begin_index, count, erase) #define DN_PArrayErase(ptr, ptr_size, index, erase) DN_TArrayEraseRange(ptr, ptr_size, index, 1, erase) #define DN_PArrayInsertArray(ptr, ptr_size, max, index, items, count) DN_TArrayInsertArray(ptr, ptr_size, max, index, items, count) @@ -4937,16 +4957,29 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 #define DN_PArrayGrowFromArena(ptr, size, ptr_max, arena, new_max) DN_ArrayGrowFromArena((void **)&(ptr), size, ptr_max, sizeof((ptr)[0]), arena, new_max) #define DN_PArrayGrowIfNeededFromPool(ptr, size, ptr_max, pool, add_count) DN_ArrayGrowIfNeededFromPool((void **)(ptr), size, ptr_max, sizeof((*ptr)[0]), pool, add_count) #define DN_PArrayGrowIfNeededFromArena(ptr, size, ptr_max, arena, add_count) DN_ArrayGrowIfNeededFromArena((void **)(ptr), size, ptr_max, sizeof((*ptr)[0]), arena, add_count) + #define DN_PArrayMakeArray(ptr, ptr_size, max, count, z_mem) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), count, z_mem) #define DN_PArrayMakeArrayZ(ptr, ptr_size, max, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), count, DN_ZMem_Yes) + #define DN_PArrayMakeArrayNoZ(ptr, ptr_size, max, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), count, DN_ZMem_No) + #define DN_PArrayMakeArrayAssert(ptr, ptr_size, max, count, z_mem) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), count, z_mem, DN_CALL_SITE) + #define DN_PArrayMakeArrayAssertZ(ptr, ptr_size, max, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), count, DN_ZMem_Yes, DN_CALL_SITE) + #define DN_PArrayMakeArrayAssertNoZ(ptr, ptr_size, max, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), count, DN_ZMem_No, DN_CALL_SITE) + #define DN_PArrayMake(ptr, ptr_size, max, z_mem) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), 1, z_mem) #define DN_PArrayMakeZ(ptr, ptr_size, max) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), 1, DN_ZMem_Yes) + #define DN_PArrayMakeNoZ(ptr, ptr_size, max) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), 1, DN_ZMem_No) + #define DN_PArrayMakeAssert(ptr, ptr_size, max, z_mem) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), 1, z_mem, DN_CALL_SITE) + #define DN_PArrayMakeAssertZ(ptr, ptr_size, max) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), 1, DN_ZMem_Yes, DN_CALL_SITE) + #define DN_PArrayMakeAssertNoZ(ptr, ptr_size, max) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), 1, DN_ZMem_No, DN_CALL_SITE) + #define DN_PArrayAddArray(ptr, ptr_size, max, items, count, add) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), items, count, add) #define DN_PArrayAdd(ptr, ptr_size, max, item, add) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, add) #define DN_PArrayAppendArray(ptr, ptr_size, max, items, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), items, count, DN_ArrayAdd_Append) #define DN_PArrayAppend(ptr, ptr_size, max, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, DN_ArrayAdd_Append) + #define DN_PArrayAppendAssert(ptr, ptr_size, max, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, DN_ArrayAdd_Append, DN_CALL_SITE) #define DN_PArrayPrependArray(ptr, ptr_size, max, items, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), items, count, DN_ArrayAdd_Prepend) #define DN_PArrayPrepend(ptr, ptr_size, max, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, DN_ArrayAdd_Prepend) + #define DN_PArrayEraseRange(ptr, ptr_size, begin_index, count, erase) DN_ArrayEraseRange(ptr, ptr_size, sizeof((ptr)[0]), begin_index, count, erase) #define DN_PArrayErase(ptr, ptr_size, index, erase) DN_ArrayEraseRange(ptr, ptr_size, sizeof((ptr)[0]), index, 1, erase) #define DN_PArrayInsertArray(ptr, ptr_size, max, index, items, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayInsertArray(ptr, ptr_size, max, sizeof((ptr)[0]), index, items, count) @@ -4963,14 +4996,26 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 #define DN_LArrayGrowFromArena(c_array, size, arena, new_max) DN_PArrayGrowFromArena(c_array, size, DN_ArrayCountU(c_array), arena, new_max) #define DN_LArrayGrowIfNeededFromPool(c_array, size, pool, add_count) DN_PArrayGrowIfNeededFromPool(c_array, size, DN_ArrayCountU(c_array), pool, add_count) #define DN_LArrayGrowIfNeededFromArena(c_array, size, arena, add_count) DN_PArrayGrowIfNeededFromArena(c_array, size, DN_ArrayCountU(c_array), arena, add_count) + #define DN_LArrayMakeArray(c_array, ptr_size, count, z_mem) DN_PArrayMakeArray(c_array, ptr_size, DN_ArrayCountU(c_array), count, z_mem) #define DN_LArrayMakeArrayZ(c_array, ptr_size, count) DN_PArrayMakeArrayZ(c_array, ptr_size, DN_ArrayCountU(c_array), count) +#define DN_LArrayMakeArrayNoZ(c_array, ptr_size, count) DN_PArrayMakeArrayNoZ(c_array, ptr_size, DN_ArrayCountU(c_array), count) +#define DN_LArrayMakeArrayAssert(c_array, ptr_size, count, z_mem) DN_PArrayMakeArrayAssert(c_array, ptr_size, DN_ArrayCountU(c_array), count, z_mem) +#define DN_LArrayMakeArrayAssertZ(c_array, ptr_size, count) DN_PArrayMakeArrayAssertZ(c_array, ptr_size, DN_ArrayCountU(c_array), count) +#define DN_LArrayMakeArrayAssertNoZ(c_array, ptr_size, count) DN_PArrayMakeArrayAssertNoZ(c_array, ptr_size, DN_ArrayCountU(c_array), count) + #define DN_LArrayMake(c_array, ptr_size, z_mem) DN_PArrayMake(c_array, ptr_size, DN_ArrayCountU(c_array), z_mem) #define DN_LArrayMakeZ(c_array, ptr_size) DN_PArrayMakeZ(c_array, ptr_size, DN_ArrayCountU(c_array)) +#define DN_LArrayMakeNoZ(c_array, ptr_size) DN_PArrayMakeNoZ(c_array, ptr_size, DN_ArrayCountU(c_array)) +#define DN_LArrayMakeAssert(c_array, ptr_size, z_mem) DN_PArrayMakeAssert(c_array, ptr_size, DN_ArrayCountU(c_array), z_mem) +#define DN_LArrayMakeAssertZ(c_array, ptr_size) DN_PArrayMakeAssertZ(c_array, ptr_size, DN_ArrayCountU(c_array)) +#define DN_LArrayMakeAssertNoZ(c_array, ptr_size) DN_PArrayMakeAssertNoZ(c_array, ptr_size, DN_ArrayCountU(c_array)) + #define DN_LArrayAddArray(c_array, ptr_size, items, count, add) DN_PArrayAddArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count, add) #define DN_LArrayAdd(c_array, ptr_size, item, add) DN_PArrayAdd(c_array, ptr_size, DN_ArrayCountU(c_array), item, add) #define DN_LArrayAppendArray(c_array, ptr_size, items, count) DN_PArrayAppendArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count) #define DN_LArrayAppend(c_array, ptr_size, item) DN_PArrayAppend(c_array, ptr_size, DN_ArrayCountU(c_array), item) +#define DN_LArrayAppendAssert(c_array, ptr_size, item) DN_PArrayAppendAssert(c_array, ptr_size, DN_ArrayCountU(c_array), item) #define DN_LArrayPrependArray(c_array, ptr_size, items, count) DN_PArrayPrependArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count) #define DN_LArrayPrepend(c_array, ptr_size, item) DN_PArrayPrepend(c_array, ptr_size, DN_ArrayCountU(c_array), item) #define DN_LArrayEraseRange(c_array, ptr_size, begin_index, count, erase) DN_PArrayEraseRange(c_array, ptr_size, begin_index, count, erase) @@ -4988,14 +5033,26 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 #define DN_IArrayGrowFromArena(ptr_array, arena, new_max) DN_PArrayGrowFromArena((ptr_array)->data, (ptr_array)->count, &(ptr_array)->max, arena, new_max) #define DN_IArrayGrowIfNeededFromPool(ptr_array, pool, add_count) DN_PArrayGrowIfNeededFromPool(&(ptr_array)->data, (ptr_array)->count, &(ptr_array)->max, pool, add_count) #define DN_IArrayGrowIfNeededFromArena(ptr_array, arena, add_count) DN_PArrayGrowIfNeededFromArena(&(ptr_array)->data, (ptr_array)->count, &(ptr_array)->max, arena, add_count) + #define DN_IArrayMakeArray(ptr_array, count, z_mem) DN_PArrayMakeArray((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, count, z_mem) #define DN_IArrayMakeArrayZ(ptr_array, count) DN_PArrayMakeArrayZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, count) +#define DN_IArrayMakeArrayNoZ(ptr_array, count) DN_PArrayMakeArrayNoZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, count) +#define DN_IArrayMakeArrayAssert(ptr_array, count, z_mem) DN_PArrayMakeArrayAssert((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, count, z_mem) +#define DN_IArrayMakeArrayAssertZ(ptr_array, count) DN_PArrayMakeArrayAssertZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, count) +#define DN_IArrayMakeArrayAssertNoZ(ptr_array, count) DN_PArrayMakeArrayAssertNoZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, count) + #define DN_IArrayMake(ptr_array, z_mem) DN_PArrayMake((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, z_mem) #define DN_IArrayMakeZ(ptr_array) DN_PArrayMakeZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max) +#define DN_IArrayMakeNoZ(ptr_array) DN_PArrayMakeNoZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max) +#define DN_IArrayMakeAssert(ptr_array, z_mem) DN_PArrayMakeAssert((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, z_mem) +#define DN_IArrayMakeAssertZ(ptr_array) DN_PArrayMakeAssertZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max) +#define DN_IArrayMakeAssertNoZ(ptr_array) DN_PArrayMakeAssertNoZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max) + #define DN_IArrayAddArray(ptr_array, items, count, add) DN_PArrayAddArray((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, items, count, add) #define DN_IArrayAdd(ptr_array, item, add) DN_PArrayAdd((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, item, add) #define DN_IArrayAppendArray(ptr_array, items, count) DN_PArrayAppendArray((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, items, count) #define DN_IArrayAppend(ptr_array, item) DN_PArrayAppend((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, item) +#define DN_IArrayAppendAssert(ptr_array, item) DN_PArrayAppendAssert((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, item) #define DN_IArrayPrependArray(ptr_array, items, count) DN_PArrayPrependArray((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, items, count) #define DN_IArrayPrepend(ptr_array, item) DN_PArrayPrepend((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, item) #define DN_IArrayEraseRange(ptr_array, begin_index, count, erase) DN_PArrayEraseRange((ptr_array)->data, &(ptr_array)->count, begin_index, count, erase) @@ -5024,7 +5081,9 @@ DN_API void* DN_ArrayPopFront (void * DN_API void* DN_ArrayPopBack (void *data, DN_USize *size, DN_USize elem_size, DN_USize count); DN_API DN_ArrayEraseResult DN_ArrayEraseRange (void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); DN_API void* DN_ArrayMakeArray (void *data, DN_USize *size, DN_USize max, DN_USize elem_size, DN_USize make_count, DN_ZMem z_mem); +DN_API void* DN_ArrayMakeArrayAssert (void *data, DN_USize *size, DN_USize max, DN_USize elem_size, DN_USize make_count, DN_ZMem z_mem, DN_CallSite call_site); DN_API void* DN_ArrayAddArray (void *data, DN_USize *size, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add); +DN_API void* DN_ArrayAddArrayAssert (void *data, DN_USize *size, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add, DN_CallSite call_site); DN_API bool DN_ArrayResizeFromPool (void **data, DN_USize *size, DN_USize *max, DN_USize elem_size, DN_Pool *pool, DN_USize new_max); DN_API bool DN_ArrayResizeFromArena (void **data, DN_USize *size, DN_USize *max, DN_USize elem_size, DN_Arena *arena, DN_USize new_max); DN_API bool DN_ArrayGrowFromPool (void **data, DN_USize size, DN_USize *max, DN_USize elem_size, DN_Pool *pool, DN_USize new_max); @@ -5040,7 +5099,11 @@ template T* DN_TArrayPopFront (T *dat template T* DN_TArrayPopBack (T *data, DN_USize *size, DN_USize count); template DN_ArrayEraseResult DN_TArrayEraseRange (T *data, DN_USize *size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); template T* DN_TArrayMakeArray (T *data, DN_USize *size, DN_USize max, DN_USize make_count, DN_ZMem z_mem); +template T* DN_TArrayMakeArrayAssert (T *data, DN_USize *size, DN_USize max, DN_USize make_count, DN_ZMem z_mem, DN_CallSite call_site); +template T* DN_TArrayMakeArrayAssertZ (T *data, DN_USize *size, DN_USize max, DN_USize make_count, DN_CallSite call_site); +template T* DN_TArrayMakeArrayAssertNoZ (T *data, DN_USize *size, DN_USize max, DN_USize make_count, DN_CallSite call_site); template T* DN_TArrayAddArray (T *data, DN_USize *size, DN_USize max, T const *elems, DN_USize elems_count, DN_ArrayAdd add); +template T* DN_TArrayAddArrayAssert (T *data, DN_USize *size, DN_USize max, T const *elems, DN_USize elems_count, DN_ArrayAdd add, DN_CallSite call_site); template bool DN_TArrayResizeFromPool (T **data, DN_USize *size, DN_USize *max, DN_Pool *pool, DN_USize new_max); template bool DN_TArrayResizeFromArena (T **data, DN_USize *size, DN_USize *max, DN_Arena *arena, DN_USize new_max); template bool DN_TArrayGrowFromPool (T **data, DN_USize size, DN_USize *max, DN_Pool *pool, DN_USize new_max); @@ -5088,6 +5151,13 @@ DN_API bool DN_DSMapKeyEquals (DN_DSMap DN_API bool operator== (DN_DSMapKey lhs, DN_DSMapKey rhs); #if defined(__cplusplus) +template T *DN_TMemCopyObj(T *dest, T const *src, DN_USize count) +{ + T* result = dest; + DN_Memcpy(dest, src, sizeof(T) * count); + return result; +} + template DN_ArrayFindResult DN_TArrayFind(T *data, DN_USize size, void const *find, DN_ArrayFindEqFunc *eq_func) { @@ -5137,6 +5207,27 @@ T *DN_TArrayMakeArray(T *data, DN_USize *size, DN_USize max, DN_USize make_count return result; } +template +T *DN_TArrayMakeArrayAssert(T *data, DN_USize *size, DN_USize max, DN_USize make_count, DN_ZMem z_mem, DN_CallSite call_site) +{ + T *result = DN_Cast(T *)DN_ArrayMakeArrayAssert(data, size, max, sizeof(*data), make_count, z_mem, call_site); + return result; +} + +template +T *DN_TArrayMakeArrayAssertZ(T *data, DN_USize *size, DN_USize max, DN_USize make_count, DN_CallSite call_site) +{ + T* result = DN_TArrayMakeArrayAssert(data, size, max, make_count, DN_ZMem_Yes, call_site); + return result; +} + +template +T *DN_TArrayMakeArrayAssertNoZ(T *data, DN_USize *size, DN_USize max, DN_USize make_count, DN_CallSite call_site) +{ + T* result = DN_TArrayMakeArrayAssert(data, size, max, make_count, DN_ZMem_No, call_site); + return result; +} + template T *DN_TArrayAddArray(T *data, DN_USize *size, DN_USize max, T const *elems, DN_USize elems_count, DN_ArrayAdd add) { @@ -5144,6 +5235,13 @@ T *DN_TArrayAddArray(T *data, DN_USize *size, DN_USize max, T const *elems, DN_U return result; } +template +T *DN_TArrayAddArrayAssert(T *data, DN_USize *size, DN_USize max, T const *elems, DN_USize elems_count, DN_ArrayAdd add, DN_CallSite call_site) +{ + T* result = DN_Cast(T *)DN_ArrayAddArrayAssert(data, size, max, sizeof(*elems), elems, elems_count, add, call_site); + return result; +} + template bool DN_TArrayResizeFromPool(T **data, DN_USize *size, DN_USize *max, DN_Pool *pool, DN_USize new_max) { @@ -6967,6 +7065,14 @@ struct DN_OSThreadLane void* shared_mem; }; +struct DN_OSThreadLaneway +{ + DN_OSThread* threads; + DN_USize threads_count; + DN_UPtr* shared_mem; + DN_OSBarrier barrier; +}; + struct DN_OSThread { DN_Str8x64 name; @@ -6978,6 +7084,7 @@ struct DN_OSThread void *user_context; DN_OSThreadFunc *func; DN_OSSemaphore init_semaphore; + DN_TCInitArgs tc_init_args; }; // NOTE: DN_OSHttp @@ -7182,14 +7289,79 @@ DN_API bool DN_OS_ConditionVariableWaitUntil (D DN_API void DN_OS_ConditionVariableSignal (DN_OSConditionVariable *cv); DN_API void DN_OS_ConditionVariableBroadcast (DN_OSConditionVariable *cv); -DN_API bool DN_OS_ThreadInit (DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, void *user_context); +DN_API bool DN_OS_ThreadInit (DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, DN_TCInitArgs tc_init_args, void *user_context); DN_API bool DN_OS_ThreadJoin (DN_OSThread *thread, DN_TCDeinitArenas deinit_arenas); DN_API DN_U32 DN_OS_ThreadID (); DN_API void DN_OS_ThreadSetNameFmt (char const *fmt, ...); +// NOTE: Thread lanes provide an abstraction to represent the concept of programming a CPU like a +// GPU, e.g. SIMT (Single Instruction Multiple Threads). The lane terminology is popularised by Ryan +// Fleury. SIMT is formally defined as +// +// Threads are grouped into warps/wavefronts (typically 32 or 64 threads) that execute the same +// instruction in lockstep, but each thread operates on different data and maintains its own state +// +// The individual threads in a wavefront on the CPU side are colloquially dubbed "lanes" and a +// thread lane here contains the necessary state to facilitate this such as the current index in the +// wavefront and synchronisation primitives to coordinate the different lanes together. +// +// The idea is to write code in a single-threaded manner (linear execution) but across multiple +// threads so that the default is all execution paths are inherently multi-threaded by default. Opt +// out of parallelism instead of opt in. This optimises for the trend of core counts increasing +// whilst clock counts remain static. +// +// A laneway is a helper function to initialise the number of requested OS threads/lanes upfront and +// setup the required synchronisation primitives. It can then be dispatched all the threads which +// start executing the `entry_point` in parallel. +// +// API +// DN_OS_ThreadLaneSync +// A blocking call to synchronise the program-counter of all other lanes in the laneway to this +// function call invocation (using an OS barrier). Optionally pass in the pointer to a pointer +// `ptr_to_share` to broadcast the pointer from one lanes to the others. The lane that wishes +// to broadcast the pointer must have a non-null pointer, all other lanes must pass in a +// non-null pointer. A typical use case might look like: +/* + DN_OSThreadLane *lane = DN_OS_TCThreadLane(); // Get lane from current (t)hread (c)context + + // NOTE: Allocate buffer in lane 0 + DN_U8 *buffer = nullptr; + if (lane->index == 0) + buffer = DN_ArenaNewArray(DN_TCMainArena(), DN_U8, DN_Gigabytes(1), DN_ZMem_No); + + // NOTE: Lane 0 broadcasts the `buffer` pointer to lane 1..N + DN_OS_ThreadLaneSync(lane, &buffer); + + // NOTE: We use LaneRange to divide the buffer into equal sized chunks that each lane can + // write into without clobbering over each other. + DN_V2USize range = DN_OS_ThreadLaneRange(lane, DN_Gigabytes(1)); + for (DN_USize index = range.begin; index < range.end; index++) { buffer[index] = index; } +*/ +// In this example, lane 0 will allocate a 1GiB buffer pass in a `buffer` to +// DN_OS_ThreadLaneSync` that is non-null. Lanes 1->N will skip the branch (because their lanes +// indexes are 1..N) and invoke `DN_OS_ThreadLaneSync` with a nullptr `buffer`. After the +// blocking call is complete, lanes 0->N will now have synchronised the `buffer` pointer and all +// lanes point to the 1GiB range allocated in lane 0's allocator. +// +// Additionally we demonstrate `DN_OS_ThreadLaneRange` which does math behind the scenes to +// divide the buffer up and assign each lane their own indices in the buffer that they can work +// on in parallel without clobbering each others work. +// +// DN_OS_ThreadLaneRange +// Calculates the range of values the current lane in the laneway should execute. For example if +// you have 128 items and 16 threads each lane will receive the following `DN_V2USize` range: +// Lane 0 => [0, 8) +// Lane 1 => [8, 16) +// ... +// Lane 16 => [120, 128) DN_API DN_OSThreadLane DN_OS_ThreadLaneInit (DN_USize index, DN_USize thread_count, DN_OSBarrier barrier, DN_UPtr *share_mem); DN_API void DN_OS_ThreadLaneSync (DN_OSThreadLane *lane, void **ptr_to_share); -DN_API DN_V2USize DN_OS_ThreadLaneRange (DN_OSThreadLane *lane, DN_USize values_count); +DN_API DN_V2USize DN_OS_ThreadLaneRange (DN_OSThreadLane const *lane, DN_USize values_count); + +DN_API DN_OSThreadLaneway DN_OS_ThreadLanewayFromArgs (DN_OSThread* threads, DN_USize threads_count, DN_UPtr* shared_mem); +DN_API DN_OSThreadLaneway DN_OS_ThreadLanewayFromArena (DN_USize threads_count, DN_Arena* arena); +DN_API void DN_OS_ThreadLanewayDispatch (DN_OSThreadLaneway *laneway, DN_OSThreadFunc *entry_point, DN_TCInitArgs tc_init_args, void *user_context); +DN_API void DN_OS_ThreadLanewayJoin (DN_OSThreadLaneway *laneway, DN_TCDeinitArenas deinit_arenas); DN_API DN_OSThreadLane* DN_OS_TCThreadLane (); DN_API void DN_OS_TCThreadLaneSync (void **ptr_to_share); @@ -7320,7 +7492,7 @@ struct DN_Core DN_USize mem_allocs_frame; DN_LeakTracker leak; - DN_U32 log_level_to_show_from; + DN_LogType log_level_to_show_from; DN_LogPrintFunc* print_func; void* print_func_context; diff --git a/Source/Base/dn_base.cpp b/Source/Base/dn_base.cpp index f5cbef0..a6159f6 100644 --- a/Source/Base/dn_base.cpp +++ b/Source/Base/dn_base.cpp @@ -4360,10 +4360,11 @@ DN_API DN_U8x32 DN_BytesFromHex64Ptr(char const *hex, DN_USize hex_count) return result; } -DN_API DN_HexU64Str8 DN_HexFromU64(DN_U64 value, DN_HexFromU64Type type) +DN_API DN_HexU64 DN_HexFromU64(DN_U64 value, DN_HexFromU64Type type) { - DN_HexU64Str8 result = {}; - DN_HexFromPtrBytes(&value, sizeof(value), result.data, sizeof(result.data), DN_TrimLeadingZero_No); + DN_HexU64 result = {}; + DN_USize size = DN_HexFromPtrBytes(&value, sizeof(value), result.data, sizeof(result.data), DN_TrimLeadingZero_No); + result.size = DN_SaturateCastUSizeToU8(size); if (type == DN_HexFromU64Type_Uppercase) { for (DN_USize index = 0; index < result.size; index++) result.data[index] = DN_CharToUpper(result.data[index]); @@ -5536,7 +5537,8 @@ DN_API void DN_LogPrint(DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags { DN_Core *dn = DN_Get(); if (type.is_u32_enum) { - if (type.u32 < dn->log_level_to_show_from) + DN_Assert(dn->log_level_to_show_from >= 0); + if (type.u32 < DN_Cast(DN_U32)dn->log_level_to_show_from) return; } diff --git a/Source/Base/dn_base.h b/Source/Base/dn_base.h index 25ef8f9..516ed71 100644 --- a/Source/Base/dn_base.h +++ b/Source/Base/dn_base.h @@ -206,33 +206,30 @@ #define DN_RawAssert(...) #define DN_Assert(...) #define DN_AssertOnce(...) + #define DN_AssertArgsF(...) #define DN_AssertF(...) #define DN_AssertFOnce(...) #else #define DN_RawAssert(expr) do { if (!(expr)) DN_DebugBreak; } while (0) - - #define DN_AssertF(expr, fmt, ...) \ + #define DN_AssertArgsF(expr, call_site, fmt, ...) \ do { \ if (!(expr)) { \ - DN_Str8 stack_trace_ = DN_Str8FromStackTraceNowHeap(128 /*limit*/, 3 /*skip*/); \ - DN_LogErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ - DN_Str8PrintFmt(stack_trace_), \ - ##__VA_ARGS__); \ - DN_DebugBreak; \ - } \ + DN_Str8 stack_trace_ = DN_Str8FromStackTraceNowHeap(128 /*limit*/, 3 /*skip*/); \ + DN_LogPrint(DN_LogTypeParamFromType(DN_LogType_Error), \ + call_site, \ + DN_LogFlags_Nil, \ + "Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ + DN_Str8PrintFmt(stack_trace_), \ + ##__VA_ARGS__); \ + DN_DebugBreak; \ + } \ } while (0) - #define DN_AssertFOnce(expr, fmt, ...) \ - do { \ - static bool once = true; \ - if (!(expr) && once) { \ - once = false; \ - DN_Str8 stack_trace_ = DN_Str8FromStackTraceNowHeap(128 /*limit*/, 3 /*skip*/); \ - DN_LogErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ - DN_Str8PrintFmt(stack_trace_), \ - ##__VA_ARGS__); \ - DN_DebugBreak; \ - } \ + #define DN_AssertF(expr, fmt, ...) DN_AssertArgsF(expr, DN_CALL_SITE, fmt, ## __VA_ARGS__) + #define DN_AssertFOnce(expr, fmt, ...) \ + do { \ + for (static bool once_ = true; !(expr) && once_; once_ = false) \ + DN_AssertF(expr, fmt, ## __VA_ARGS__); \ } while (0) #define DN_Assert(expr) DN_AssertF((expr), "") @@ -639,7 +636,7 @@ struct DN_Hex32 { char data[32 + 1]; DN_USize size; }; struct DN_Hex64 { char data[64 + 1]; DN_USize size; }; struct DN_Hex128 { char data[128 + 1]; DN_USize size; }; -struct DN_HexU64Str8 +struct DN_HexU64 { char data[(sizeof(DN_U64) * 2) + 1 /*null-terminator*/]; DN_U8 size; @@ -1564,7 +1561,7 @@ struct DN_ArrayEraseResult // // for (DN_USize index = 0; index < array.size; index++) { // if (erase) - // index = DN_ArrayEraseRange(&array, index, -3, DN_ArrayErase_Unstable).it_index; + // index = DN_FArray_EraseRange(&array, index, -3, DN_ArrayErase_Unstable); // } DN_USize it_index; DN_USize items_erased; // The number of items erased @@ -1655,6 +1652,12 @@ DN_MSVC_WARNING_POP DN_API bool DN_MemStartsWith (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); DN_API bool DN_MemEqUnsafe (void const *lhs, void const *rhs, DN_USize size); +#if defined(__cplusplus) +template T* DN_TMemCopyObj (T *dest, T const *src, DN_USize count); +#define DN_MemCopyObj(dest, src, count) DN_TMemCopyObj(dest, src, count) +#else +#define DN_MemCopyObj(dest, src, count) DN_Memcpy(dest, src, sizeof(*src) * count) +#endif DN_API DN_U64 DN_AtomicSetValue64 (DN_U64 volatile *target, DN_U64 value); DN_API DN_U32 DN_AtomicSetValue32 (DN_U32 volatile *target, DN_U32 value); @@ -2132,7 +2135,7 @@ DN_API DN_Str8 DN_BytesFromHexPtrPool DN_API DN_U8x16 DN_BytesFromHex32Ptr (char const *hex, DN_USize hex_count); DN_API DN_U8x32 DN_BytesFromHex64Ptr (char const *hex, DN_USize hex_count); -DN_API DN_HexU64Str8 DN_HexFromU64 (DN_U64 value, DN_HexFromU64Type type); +DN_API DN_HexU64 DN_HexFromU64 (DN_U64 value, DN_HexFromU64Type type); DN_API DN_USize DN_HexFromPtrBytes (void const *bytes, DN_USize bytes_count, void *hex, DN_USize hex_count, DN_TrimLeadingZero trim_leading_z); DN_API DN_Str8 DN_HexFromPtrBytesArena (void const *bytes, DN_USize bytes_count, DN_Arena *arena, DN_TrimLeadingZero trim_leading_z); DN_API DN_USize DN_HexFromStr8Bytes (DN_Str8 bytes, void *hex, DN_USize hex_count, DN_TrimLeadingZero trim_leading_z); @@ -2766,6 +2769,8 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 if ((head)) { \ (ptr)->next = (head)->next; \ (head)->next = (ptr); \ + if ((ptr)->next) \ + (ptr)->next->prev = (ptr); \ } else { \ (head) = (ptr); \ } \ @@ -2781,6 +2786,8 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 if ((head)) { \ (ptr)->prev = (head)->prev; \ (head)->prev = (ptr); \ + if ((ptr)->prev) \ + (ptr)->prev->next = (ptr); \ } else { \ (head) = (ptr); \ } \ @@ -2837,16 +2844,29 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 #define DN_PArrayGrowFromArena(ptr, size, ptr_max, arena, new_max) DN_TArrayGrowFromArena(&(ptr), size, ptr_max, arena, new_max) #define DN_PArrayGrowIfNeededFromPool(ptr, size, ptr_max, pool, add_count) DN_TArrayGrowIfNeededFromPool(ptr, size, ptr_max, pool, add_count) #define DN_PArrayGrowIfNeededFromArena(ptr, size, ptr_max, arena, add_count) DN_TArrayGrowIfNeededFromArena(ptr, size, ptr_max, arena, add_count) + #define DN_PArrayMakeArray(ptr, ptr_size, max, count, z_mem) DN_TArrayMakeArray(ptr, ptr_size, max, count, z_mem) #define DN_PArrayMakeArrayZ(ptr, ptr_size, max, count) DN_TArrayMakeArray(ptr, ptr_size, max, count, DN_ZMem_Yes) + #define DN_PArrayMakeArrayNoZ(ptr, ptr_size, max, count) DN_TArrayMakeArray(ptr, ptr_size, max, count, DN_ZMem_No) + #define DN_PArrayMakeArrayAssert(ptr, ptr_size, max, count, z_mem) DN_TArrayMakeArrayAssert(ptr, ptr_size, max, count, z_mem, DN_CALL_SITE) + #define DN_PArrayMakeArrayAssertZ(ptr, ptr_size, max, count) DN_TArrayMakeArrayAssert(ptr, ptr_size, max, count, DN_ZMem_Yes, DN_CALL_SITE) + #define DN_PArrayMakeArrayAssertNoZ(ptr, ptr_size, max, count) DN_TArrayMakeArrayAssert(ptr, ptr_size, max, count, DN_ZMem_No, DN_CALL_SITE) + #define DN_PArrayMake(ptr, ptr_size, max, z_mem) DN_TArrayMakeArray(ptr, ptr_size, max, 1, z_mem) #define DN_PArrayMakeZ(ptr, ptr_size, max) DN_TArrayMakeArray(ptr, ptr_size, max, 1, DN_ZMem_Yes) + #define DN_PArrayMakeNoZ(ptr, ptr_size, max) DN_TArrayMakeArray(ptr, ptr_size, max, 1, DN_ZMem_No) + #define DN_PArrayMakeAssert(ptr, ptr_size, max, z_mem) DN_TArrayMakeArrayAssert(ptr, ptr_size, max, 1, z_mem, DN_CALL_SITE) + #define DN_PArrayMakeAssertZ(ptr, ptr_size, max) DN_TArrayMakeArrayAssert(ptr, ptr_size, max, 1, DN_ZMem_Yes, DN_CALL_SITE) + #define DN_PArrayMakeAssertNoZ(ptr, ptr_size, max) DN_TArrayMakeArrayAssert(ptr, ptr_size, max, 1, DN_ZMem_No, DN_CALL_SITE) + #define DN_PArrayAddArray(ptr, ptr_size, max, items, count, add) DN_TArrayAddArray(ptr, ptr_size, max, items, count, add) #define DN_PArrayAdd(ptr, ptr_size, max, item, add) DN_TArrayAddArray(ptr, ptr_size, max, &item, 1, add) #define DN_PArrayAppendArray(ptr, ptr_size, max, items, count) DN_TArrayAddArray(ptr, ptr_size, max, items, count, DN_ArrayAdd_Append) #define DN_PArrayAppend(ptr, ptr_size, max, item) DN_TArrayAddArray(ptr, ptr_size, max, &item, 1, DN_ArrayAdd_Append) + #define DN_PArrayAppendAssert(ptr, ptr_size, max, item) DN_TArrayAddArrayAssert(ptr, ptr_size, max, &item, 1, DN_ArrayAdd_Append, DN_CALL_SITE) #define DN_PArrayPrependArray(ptr, ptr_size, max, items, count) DN_TArrayAddArray(ptr, ptr_size, max, items, count, DN_ArrayAdd_Prepend) #define DN_PArrayPrepend(ptr, ptr_size, max, item) DN_TArrayAddArray(ptr, ptr_size, max, &item, 1, DN_ArrayAdd_Prepend) + #define DN_PArrayEraseRange(ptr, ptr_size, begin_index, count, erase) DN_TArrayEraseRange(ptr, ptr_size, begin_index, count, erase) #define DN_PArrayErase(ptr, ptr_size, index, erase) DN_TArrayEraseRange(ptr, ptr_size, index, 1, erase) #define DN_PArrayInsertArray(ptr, ptr_size, max, index, items, count) DN_TArrayInsertArray(ptr, ptr_size, max, index, items, count) @@ -2862,16 +2882,29 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 #define DN_PArrayGrowFromArena(ptr, size, ptr_max, arena, new_max) DN_ArrayGrowFromArena((void **)&(ptr), size, ptr_max, sizeof((ptr)[0]), arena, new_max) #define DN_PArrayGrowIfNeededFromPool(ptr, size, ptr_max, pool, add_count) DN_ArrayGrowIfNeededFromPool((void **)(ptr), size, ptr_max, sizeof((*ptr)[0]), pool, add_count) #define DN_PArrayGrowIfNeededFromArena(ptr, size, ptr_max, arena, add_count) DN_ArrayGrowIfNeededFromArena((void **)(ptr), size, ptr_max, sizeof((*ptr)[0]), arena, add_count) + #define DN_PArrayMakeArray(ptr, ptr_size, max, count, z_mem) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), count, z_mem) #define DN_PArrayMakeArrayZ(ptr, ptr_size, max, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), count, DN_ZMem_Yes) + #define DN_PArrayMakeArrayNoZ(ptr, ptr_size, max, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), count, DN_ZMem_No) + #define DN_PArrayMakeArrayAssert(ptr, ptr_size, max, count, z_mem) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), count, z_mem, DN_CALL_SITE) + #define DN_PArrayMakeArrayAssertZ(ptr, ptr_size, max, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), count, DN_ZMem_Yes, DN_CALL_SITE) + #define DN_PArrayMakeArrayAssertNoZ(ptr, ptr_size, max, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), count, DN_ZMem_No, DN_CALL_SITE) + #define DN_PArrayMake(ptr, ptr_size, max, z_mem) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), 1, z_mem) #define DN_PArrayMakeZ(ptr, ptr_size, max) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), 1, DN_ZMem_Yes) + #define DN_PArrayMakeNoZ(ptr, ptr_size, max) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), 1, DN_ZMem_No) + #define DN_PArrayMakeAssert(ptr, ptr_size, max, z_mem) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), 1, z_mem, DN_CALL_SITE) + #define DN_PArrayMakeAssertZ(ptr, ptr_size, max) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), 1, DN_ZMem_Yes, DN_CALL_SITE) + #define DN_PArrayMakeAssertNoZ(ptr, ptr_size, max) (DN_CppDeclType(&(ptr)[0]))DN_ArrayMakeArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), 1, DN_ZMem_No, DN_CALL_SITE) + #define DN_PArrayAddArray(ptr, ptr_size, max, items, count, add) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), items, count, add) #define DN_PArrayAdd(ptr, ptr_size, max, item, add) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, add) #define DN_PArrayAppendArray(ptr, ptr_size, max, items, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), items, count, DN_ArrayAdd_Append) #define DN_PArrayAppend(ptr, ptr_size, max, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, DN_ArrayAdd_Append) + #define DN_PArrayAppendAssert(ptr, ptr_size, max, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArrayAssert(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, DN_ArrayAdd_Append, DN_CALL_SITE) #define DN_PArrayPrependArray(ptr, ptr_size, max, items, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), items, count, DN_ArrayAdd_Prepend) #define DN_PArrayPrepend(ptr, ptr_size, max, item) (DN_CppDeclType(&(ptr)[0]))DN_ArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, DN_ArrayAdd_Prepend) + #define DN_PArrayEraseRange(ptr, ptr_size, begin_index, count, erase) DN_ArrayEraseRange(ptr, ptr_size, sizeof((ptr)[0]), begin_index, count, erase) #define DN_PArrayErase(ptr, ptr_size, index, erase) DN_ArrayEraseRange(ptr, ptr_size, sizeof((ptr)[0]), index, 1, erase) #define DN_PArrayInsertArray(ptr, ptr_size, max, index, items, count) (DN_CppDeclType(&(ptr)[0]))DN_ArrayInsertArray(ptr, ptr_size, max, sizeof((ptr)[0]), index, items, count) @@ -2888,14 +2921,26 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 #define DN_LArrayGrowFromArena(c_array, size, arena, new_max) DN_PArrayGrowFromArena(c_array, size, DN_ArrayCountU(c_array), arena, new_max) #define DN_LArrayGrowIfNeededFromPool(c_array, size, pool, add_count) DN_PArrayGrowIfNeededFromPool(c_array, size, DN_ArrayCountU(c_array), pool, add_count) #define DN_LArrayGrowIfNeededFromArena(c_array, size, arena, add_count) DN_PArrayGrowIfNeededFromArena(c_array, size, DN_ArrayCountU(c_array), arena, add_count) + #define DN_LArrayMakeArray(c_array, ptr_size, count, z_mem) DN_PArrayMakeArray(c_array, ptr_size, DN_ArrayCountU(c_array), count, z_mem) #define DN_LArrayMakeArrayZ(c_array, ptr_size, count) DN_PArrayMakeArrayZ(c_array, ptr_size, DN_ArrayCountU(c_array), count) +#define DN_LArrayMakeArrayNoZ(c_array, ptr_size, count) DN_PArrayMakeArrayNoZ(c_array, ptr_size, DN_ArrayCountU(c_array), count) +#define DN_LArrayMakeArrayAssert(c_array, ptr_size, count, z_mem) DN_PArrayMakeArrayAssert(c_array, ptr_size, DN_ArrayCountU(c_array), count, z_mem) +#define DN_LArrayMakeArrayAssertZ(c_array, ptr_size, count) DN_PArrayMakeArrayAssertZ(c_array, ptr_size, DN_ArrayCountU(c_array), count) +#define DN_LArrayMakeArrayAssertNoZ(c_array, ptr_size, count) DN_PArrayMakeArrayAssertNoZ(c_array, ptr_size, DN_ArrayCountU(c_array), count) + #define DN_LArrayMake(c_array, ptr_size, z_mem) DN_PArrayMake(c_array, ptr_size, DN_ArrayCountU(c_array), z_mem) #define DN_LArrayMakeZ(c_array, ptr_size) DN_PArrayMakeZ(c_array, ptr_size, DN_ArrayCountU(c_array)) +#define DN_LArrayMakeNoZ(c_array, ptr_size) DN_PArrayMakeNoZ(c_array, ptr_size, DN_ArrayCountU(c_array)) +#define DN_LArrayMakeAssert(c_array, ptr_size, z_mem) DN_PArrayMakeAssert(c_array, ptr_size, DN_ArrayCountU(c_array), z_mem) +#define DN_LArrayMakeAssertZ(c_array, ptr_size) DN_PArrayMakeAssertZ(c_array, ptr_size, DN_ArrayCountU(c_array)) +#define DN_LArrayMakeAssertNoZ(c_array, ptr_size) DN_PArrayMakeAssertNoZ(c_array, ptr_size, DN_ArrayCountU(c_array)) + #define DN_LArrayAddArray(c_array, ptr_size, items, count, add) DN_PArrayAddArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count, add) #define DN_LArrayAdd(c_array, ptr_size, item, add) DN_PArrayAdd(c_array, ptr_size, DN_ArrayCountU(c_array), item, add) #define DN_LArrayAppendArray(c_array, ptr_size, items, count) DN_PArrayAppendArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count) #define DN_LArrayAppend(c_array, ptr_size, item) DN_PArrayAppend(c_array, ptr_size, DN_ArrayCountU(c_array), item) +#define DN_LArrayAppendAssert(c_array, ptr_size, item) DN_PArrayAppendAssert(c_array, ptr_size, DN_ArrayCountU(c_array), item) #define DN_LArrayPrependArray(c_array, ptr_size, items, count) DN_PArrayPrependArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count) #define DN_LArrayPrepend(c_array, ptr_size, item) DN_PArrayPrepend(c_array, ptr_size, DN_ArrayCountU(c_array), item) #define DN_LArrayEraseRange(c_array, ptr_size, begin_index, count, erase) DN_PArrayEraseRange(c_array, ptr_size, begin_index, count, erase) @@ -2913,14 +2958,26 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2 #define DN_IArrayGrowFromArena(ptr_array, arena, new_max) DN_PArrayGrowFromArena((ptr_array)->data, (ptr_array)->count, &(ptr_array)->max, arena, new_max) #define DN_IArrayGrowIfNeededFromPool(ptr_array, pool, add_count) DN_PArrayGrowIfNeededFromPool(&(ptr_array)->data, (ptr_array)->count, &(ptr_array)->max, pool, add_count) #define DN_IArrayGrowIfNeededFromArena(ptr_array, arena, add_count) DN_PArrayGrowIfNeededFromArena(&(ptr_array)->data, (ptr_array)->count, &(ptr_array)->max, arena, add_count) + #define DN_IArrayMakeArray(ptr_array, count, z_mem) DN_PArrayMakeArray((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, count, z_mem) #define DN_IArrayMakeArrayZ(ptr_array, count) DN_PArrayMakeArrayZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, count) +#define DN_IArrayMakeArrayNoZ(ptr_array, count) DN_PArrayMakeArrayNoZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, count) +#define DN_IArrayMakeArrayAssert(ptr_array, count, z_mem) DN_PArrayMakeArrayAssert((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, count, z_mem) +#define DN_IArrayMakeArrayAssertZ(ptr_array, count) DN_PArrayMakeArrayAssertZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, count) +#define DN_IArrayMakeArrayAssertNoZ(ptr_array, count) DN_PArrayMakeArrayAssertNoZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, count) + #define DN_IArrayMake(ptr_array, z_mem) DN_PArrayMake((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, z_mem) #define DN_IArrayMakeZ(ptr_array) DN_PArrayMakeZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max) +#define DN_IArrayMakeNoZ(ptr_array) DN_PArrayMakeNoZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max) +#define DN_IArrayMakeAssert(ptr_array, z_mem) DN_PArrayMakeAssert((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, z_mem) +#define DN_IArrayMakeAssertZ(ptr_array) DN_PArrayMakeAssertZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max) +#define DN_IArrayMakeAssertNoZ(ptr_array) DN_PArrayMakeAssertNoZ((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max) + #define DN_IArrayAddArray(ptr_array, items, count, add) DN_PArrayAddArray((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, items, count, add) #define DN_IArrayAdd(ptr_array, item, add) DN_PArrayAdd((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, item, add) #define DN_IArrayAppendArray(ptr_array, items, count) DN_PArrayAppendArray((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, items, count) #define DN_IArrayAppend(ptr_array, item) DN_PArrayAppend((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, item) +#define DN_IArrayAppendAssert(ptr_array, item) DN_PArrayAppendAssert((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, item) #define DN_IArrayPrependArray(ptr_array, items, count) DN_PArrayPrependArray((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, items, count) #define DN_IArrayPrepend(ptr_array, item) DN_PArrayPrepend((ptr_array)->data, &(ptr_array)->count, (ptr_array)->max, item) #define DN_IArrayEraseRange(ptr_array, begin_index, count, erase) DN_PArrayEraseRange((ptr_array)->data, &(ptr_array)->count, begin_index, count, erase) @@ -2949,7 +3006,9 @@ DN_API void* DN_ArrayPopFront (void * DN_API void* DN_ArrayPopBack (void *data, DN_USize *size, DN_USize elem_size, DN_USize count); DN_API DN_ArrayEraseResult DN_ArrayEraseRange (void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); DN_API void* DN_ArrayMakeArray (void *data, DN_USize *size, DN_USize max, DN_USize elem_size, DN_USize make_count, DN_ZMem z_mem); +DN_API void* DN_ArrayMakeArrayAssert (void *data, DN_USize *size, DN_USize max, DN_USize elem_size, DN_USize make_count, DN_ZMem z_mem, DN_CallSite call_site); DN_API void* DN_ArrayAddArray (void *data, DN_USize *size, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add); +DN_API void* DN_ArrayAddArrayAssert (void *data, DN_USize *size, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add, DN_CallSite call_site); DN_API bool DN_ArrayResizeFromPool (void **data, DN_USize *size, DN_USize *max, DN_USize elem_size, DN_Pool *pool, DN_USize new_max); DN_API bool DN_ArrayResizeFromArena (void **data, DN_USize *size, DN_USize *max, DN_USize elem_size, DN_Arena *arena, DN_USize new_max); DN_API bool DN_ArrayGrowFromPool (void **data, DN_USize size, DN_USize *max, DN_USize elem_size, DN_Pool *pool, DN_USize new_max); @@ -2965,7 +3024,11 @@ template T* DN_TArrayPopFront (T *dat template T* DN_TArrayPopBack (T *data, DN_USize *size, DN_USize count); template DN_ArrayEraseResult DN_TArrayEraseRange (T *data, DN_USize *size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); template T* DN_TArrayMakeArray (T *data, DN_USize *size, DN_USize max, DN_USize make_count, DN_ZMem z_mem); +template T* DN_TArrayMakeArrayAssert (T *data, DN_USize *size, DN_USize max, DN_USize make_count, DN_ZMem z_mem, DN_CallSite call_site); +template T* DN_TArrayMakeArrayAssertZ (T *data, DN_USize *size, DN_USize max, DN_USize make_count, DN_CallSite call_site); +template T* DN_TArrayMakeArrayAssertNoZ (T *data, DN_USize *size, DN_USize max, DN_USize make_count, DN_CallSite call_site); template T* DN_TArrayAddArray (T *data, DN_USize *size, DN_USize max, T const *elems, DN_USize elems_count, DN_ArrayAdd add); +template T* DN_TArrayAddArrayAssert (T *data, DN_USize *size, DN_USize max, T const *elems, DN_USize elems_count, DN_ArrayAdd add, DN_CallSite call_site); template bool DN_TArrayResizeFromPool (T **data, DN_USize *size, DN_USize *max, DN_Pool *pool, DN_USize new_max); template bool DN_TArrayResizeFromArena (T **data, DN_USize *size, DN_USize *max, DN_Arena *arena, DN_USize new_max); template bool DN_TArrayGrowFromPool (T **data, DN_USize size, DN_USize *max, DN_Pool *pool, DN_USize new_max); @@ -3013,6 +3076,13 @@ DN_API bool DN_DSMapKeyEquals (DN_DSMap DN_API bool operator== (DN_DSMapKey lhs, DN_DSMapKey rhs); #if defined(__cplusplus) +template T *DN_TMemCopyObj(T *dest, T const *src, DN_USize count) +{ + T* result = dest; + DN_Memcpy(dest, src, sizeof(T) * count); + return result; +} + template DN_ArrayFindResult DN_TArrayFind(T *data, DN_USize size, void const *find, DN_ArrayFindEqFunc *eq_func) { @@ -3062,6 +3132,27 @@ T *DN_TArrayMakeArray(T *data, DN_USize *size, DN_USize max, DN_USize make_count return result; } +template +T *DN_TArrayMakeArrayAssert(T *data, DN_USize *size, DN_USize max, DN_USize make_count, DN_ZMem z_mem, DN_CallSite call_site) +{ + T *result = DN_Cast(T *)DN_ArrayMakeArrayAssert(data, size, max, sizeof(*data), make_count, z_mem, call_site); + return result; +} + +template +T *DN_TArrayMakeArrayAssertZ(T *data, DN_USize *size, DN_USize max, DN_USize make_count, DN_CallSite call_site) +{ + T* result = DN_TArrayMakeArrayAssert(data, size, max, make_count, DN_ZMem_Yes, call_site); + return result; +} + +template +T *DN_TArrayMakeArrayAssertNoZ(T *data, DN_USize *size, DN_USize max, DN_USize make_count, DN_CallSite call_site) +{ + T* result = DN_TArrayMakeArrayAssert(data, size, max, make_count, DN_ZMem_No, call_site); + return result; +} + template T *DN_TArrayAddArray(T *data, DN_USize *size, DN_USize max, T const *elems, DN_USize elems_count, DN_ArrayAdd add) { @@ -3069,6 +3160,13 @@ T *DN_TArrayAddArray(T *data, DN_USize *size, DN_USize max, T const *elems, DN_U return result; } +template +T *DN_TArrayAddArrayAssert(T *data, DN_USize *size, DN_USize max, T const *elems, DN_USize elems_count, DN_ArrayAdd add, DN_CallSite call_site) +{ + T* result = DN_Cast(T *)DN_ArrayAddArrayAssert(data, size, max, sizeof(*elems), elems, elems_count, add, call_site); + return result; +} + template bool DN_TArrayResizeFromPool(T **data, DN_USize *size, DN_USize *max, DN_Pool *pool, DN_USize new_max) { diff --git a/Source/Base/dn_base_containers.cpp b/Source/Base/dn_base_containers.cpp index a8bd93d..f618075 100644 --- a/Source/Base/dn_base_containers.cpp +++ b/Source/Base/dn_base_containers.cpp @@ -107,6 +107,7 @@ DN_API void *DN_ArrayPopBack(void *data, DN_USize *size, DN_USize elem_size, DN_ DN_API DN_ArrayEraseResult DN_ArrayEraseRange(void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase) { DN_ArrayEraseResult result = {}; + result.it_index = begin_index; if (!data || !size || *size == 0 || count == 0) return result; @@ -163,6 +164,13 @@ DN_API void *DN_ArrayMakeArray(void *data, DN_USize *size, DN_USize max, DN_USiz return result; } +DN_API void *DN_ArrayMakeArrayAssert(void *data, DN_USize *size, DN_USize max, DN_USize elem_size, DN_USize make_count, DN_ZMem z_mem, DN_CallSite call_site) +{ + void *result = DN_ArrayMakeArray(data, size, max, elem_size, make_count, z_mem); + DN_AssertArgsF(result, call_site, "array=%p size=%zu max=%zu", data, *size, max); + return result; +} + DN_API void *DN_ArrayAddArray(void *data, DN_USize *size, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add) { void *result = DN_ArrayMakeArray(data, size, max, elem_size, elems_count, DN_ZMem_No); @@ -179,6 +187,13 @@ DN_API void *DN_ArrayAddArray(void *data, DN_USize *size, DN_USize max, DN_USize return result; } +DN_API void *DN_ArrayAddArrayAssert(void *data, DN_USize *size, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add, DN_CallSite call_site) +{ + void *result = DN_ArrayAddArray(data, size, max, elem_size, elems, elems_count, add); + DN_AssertArgsF(result, call_site, "array=%p size=%zu max=%zu", data, *size, max); + return result; +} + DN_API bool DN_ArrayResizeFromArena(void **data, DN_USize *size, DN_USize *max, DN_USize elem_size, DN_Pool *pool, DN_USize new_max) { bool result = true; diff --git a/Source/Extra/dn_async.cpp b/Source/Extra/dn_async.cpp index cd4936e..2368f8e 100644 --- a/Source/Extra/dn_async.cpp +++ b/Source/Extra/dn_async.cpp @@ -53,7 +53,7 @@ DN_API void DN_ASYNC_Init(DN_ASYNCCore *async, char *base, DN_USize base_size, D async->threads = threads; for (DN_ForIndexU(index, async->thread_count)) { DN_OSThread *thread = async->threads + index; - DN_OS_ThreadInit(thread, DN_ASYNC_ThreadEntryPoint_, nullptr, async); + DN_OS_ThreadInit(thread, DN_ASYNC_ThreadEntryPoint_, /*lane=*/ nullptr, DN_TCInitArgsDefault(), async); } } diff --git a/Source/Extra/dn_bin_pack.cpp b/Source/Extra/dn_bin_pack.cpp index 46432ab..e2ab4d9 100644 --- a/Source/Extra/dn_bin_pack.cpp +++ b/Source/Extra/dn_bin_pack.cpp @@ -201,6 +201,6 @@ DN_API void DN_BinPackCBuffer(DN_BinPack *pack, DN_BinPackMode mode, char *ptr, DN_API DN_Str8 DN_BinPackBuild(DN_BinPack const *pack, DN_Arena *arena) { - DN_Str8 result = DN_Str8FromStr8BuilderArena(&pack->writer, arena); + DN_Str8 result = DN_Str8BuilderBuild(&pack->writer, arena); return result; } diff --git a/Source/Extra/dn_net.cpp b/Source/Extra/dn_net.cpp index 211bc20..9fed954 100644 --- a/Source/Extra/dn_net.cpp +++ b/Source/Extra/dn_net.cpp @@ -127,6 +127,4 @@ void DN_NET_EndFinishedRequest(DN_NETRequest *request) { // NOTE: Deallocate the memory used in the request and reset the string builder DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes); - // NOTE: Check that the request is completely detached - DN_Assert(request->next == nullptr); } diff --git a/Source/Extra/dn_net_curl.cpp b/Source/Extra/dn_net_curl.cpp index fee143d..4bb962e 100644 --- a/Source/Extra/dn_net_curl.cpp +++ b/Source/Extra/dn_net_curl.cpp @@ -112,7 +112,7 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread) DN_Assert(req->response.state == DN_NETResponseState_Nil); DN_Assert(req->type != DN_NETRequestType_Nil); - // NOTE: Attach it to the CURL thread's request list + // NOTE: Attach it to the CURL thread's request list for (DN_OS_MutexScope(&curl->list_mutex)) { DN_Assert(DN_NET_CurlRequestIsInList(curl->request_list, req)); DN_DoublyLLDetach(curl->request_list, req); @@ -174,13 +174,21 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread) DN_Assert(event.request.handle != 0); DN_NETRequest *request = DN_Cast(DN_NETRequest *) event.request.handle; - // NOTE: Release resources + // NOTE: Detach the request from the deinit list. This brings the request into this + // thread's provenance, no other threads modifying the deinit list will race with us. + for (DN_OS_MutexScope(&curl->list_mutex)) { + DN_Assert(DN_NET_CurlRequestIsInList(curl->deinit_list, request)); + DN_DoublyLLDetach(curl->deinit_list, request); + } + + // NOTE: Now we can modify the request, release resources DN_NET_EndFinishedRequest(request); DN_OS_SemaphoreDeinit(&request->completion_sem); curl_multi_remove_handle(curl->thread_curlm, curl_req->handle); curl_slist_free_all(curl_req->slist); curl_easy_reset(curl_req->handle); + CURL *copy = curl_req->handle; *curl_req = {}; curl_req->handle = copy; @@ -190,14 +198,11 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread) resetter.arena = request->arena; resetter.gen = request->gen; DN_Memcpy(resetter.context, request->context, sizeof(resetter.context)); - *request = resetter; + *request = resetter; // NOTE: Add it to the free list - for (DN_OS_MutexScope(&curl->list_mutex)) { - DN_Assert(DN_NET_CurlRequestIsInList(curl->deinit_list, request)); - DN_DoublyLLDetach(curl->deinit_list, request); + for (DN_OS_MutexScope(&curl->list_mutex)) DN_DoublyLLAppend(curl->free_list, request); - } } break; } } @@ -374,7 +379,7 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread) } DN_NETRequest *request_copy = req; - req = req->prev; + req = req->prev; DN_NET_CurlMarkRequestDone_(net, request_copy); if (!req) break; @@ -418,7 +423,7 @@ void DN_NET_CurlInit(DN_NETCore *net, char *base, DN_U64 base_size) 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_OS_ThreadInit(&curl->thread, DN_NET_CurlThreadEntryPoint_, nullptr, net); + DN_OS_ThreadInit(&curl->thread, DN_NET_CurlThreadEntryPoint_, nullptr, DN_TCInitArgsDefault(), net); } void DN_NET_CurlDeinit(DN_NETCore *net) @@ -445,13 +450,16 @@ static DN_NETRequestHandle DN_NET_CurlDoRequest_(DN_NETCore *net, DN_Str8 url, D // NOTE None in the free list so allocate one if (!req) { + DN_OS_MutexLock(&curl_core->list_mutex); DN_U64 arena_pos = DN_MemListPos(net->arena.mem); - req = DN_ArenaNew(&net->arena, DN_NETRequest, DN_ZMem_Yes); - DN_NETCurlRequest *curl_req = DN_ArenaNew(&net->arena, DN_NETCurlRequest, DN_ZMem_Yes); + req = DN_ArenaNewZ(&net->arena, DN_NETRequest); + DN_NETCurlRequest *curl_req = DN_ArenaNewZ(&net->arena, DN_NETCurlRequest); if (!req || !curl_req) { DN_MemListPopTo(net->arena.mem, arena_pos); + DN_OS_MutexUnlock(&curl_core->list_mutex); return result; } + DN_OS_MutexUnlock(&curl_core->list_mutex); curl_req->handle = DN_Cast(CURL *) curl_easy_init(); req->context[0] = DN_Cast(DN_UPtr) curl_req; diff --git a/Source/Extra/dn_net_emscripten.cpp b/Source/Extra/dn_net_emscripten.cpp index 39544da..f770ddc 100644 --- a/Source/Extra/dn_net_emscripten.cpp +++ b/Source/Extra/dn_net_emscripten.cpp @@ -148,7 +148,7 @@ static void DN_NET_EmcHTTPProgressCallback(emscripten_fetch_t *fetch) void DN_NET_EmcInit(DN_NETCore *net, char *base, DN_U64 base_size) { - DN_NET_BaseInit_(net, base, base_size); + DN_NET_BaseInit(net, base, base_size); DN_NETEmcCore *emc = DN_ArenaNew(&net->arena, DN_NETEmcCore, DN_ZMem_Yes); emc->pool = DN_PoolFromArena(&net->arena, 0); net->context = emc; @@ -192,7 +192,7 @@ static DN_NETRequest *DN_NET_EmcAllocRequest_(DN_NETCore *net) DN_NETRequestHandle DN_NET_EmcDoHTTP(DN_NETCore *net, DN_Str8 url, DN_Str8 method, DN_NETDoHTTPArgs const *args) { DN_NETRequest *req = DN_NET_EmcAllocRequest_(net); - DN_NETRequestHandle result = DN_NET_SetupRequest_(req, url, method, args, DN_NETRequestType_HTTP); + DN_NETRequestHandle result = DN_NET_SetupRequest(req, url, method, args, DN_NETRequestType_HTTP); // NOTE: Setup the HTTP request via Emscripten emscripten_fetch_attr_t fetch_attribs = {}; @@ -254,7 +254,7 @@ DN_NETRequestHandle DN_NET_EmcDoWS(DN_NETCore *net, DN_Str8 url) { DN_Assert(emscripten_websocket_is_supported()); DN_NETRequest *req = DN_NET_EmcAllocRequest_(net); - DN_NETRequestHandle result = DN_NET_SetupRequest_(req, url, /*method=*/DN_Str8Lit(""), /*args=*/nullptr, DN_NETRequestType_WS); + DN_NETRequestHandle result = DN_NET_SetupRequest(req, url, /*method=*/DN_Str8Lit(""), /*args=*/nullptr, DN_NETRequestType_WS); if (!req) return result; @@ -376,7 +376,7 @@ static DN_NETResponse DN_NET_EmcHandleFinishedRequest_(DN_NETCore *net, DN_NETEm } if (end_request) { - DN_NET_EndFinishedRequest_(request); + DN_NET_EndFinishedRequest(request); emscripten_websocket_delete(emc_request->socket); emc_request->socket = 0; diff --git a/Source/Extra/dn_tests.cpp b/Source/Extra/dn_tests.cpp index 4960c92..daeca15 100644 --- a/Source/Extra/dn_tests.cpp +++ b/Source/Extra/dn_tests.cpp @@ -1222,7 +1222,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 5, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 2); - DN_UT_AssertF(&result, erase.it_index == 2, "erase.it_index=%zu", erase.it_index); + DN_UT_Assert(&result, erase.it_index == 3); DN_UT_Assert(&result, size == 8); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -1233,7 +1233,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 3); - DN_UT_Assert(&result, erase.it_index == 2); + DN_UT_Assert(&result, erase.it_index == 3); DN_UT_Assert(&result, size == 7); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -1244,7 +1244,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -1, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 3, 4, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 1); - DN_UT_Assert(&result, erase.it_index == 4); + DN_UT_Assert(&result, erase.it_index == 5); DN_UT_Assert(&result, size == 9); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -1255,7 +1255,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Unstable); int expected[] = {0, 1, 2, 8, 9, 5, 6, 7}; DN_UT_Assert(&result, erase.items_erased == 2); - DN_UT_Assert(&result, erase.it_index == 2); + DN_UT_Assert(&result, erase.it_index == 3); DN_UT_Assert(&result, size == 8); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -1266,7 +1266,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Unstable); int expected[] = {0, 1, 2, 7, 8, 9, 6}; DN_UT_Assert(&result, erase.items_erased == 3); - DN_UT_Assert(&result, erase.it_index == 2); + DN_UT_Assert(&result, erase.it_index == 3); DN_UT_Assert(&result, size == 7); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -1288,7 +1288,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 9, 2, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; DN_UT_Assert(&result, erase.items_erased == 1); - DN_UT_Assert(&result, erase.it_index == 8); + DN_UT_Assert(&result, erase.it_index == 9); DN_UT_Assert(&result, size == 9); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } @@ -1334,7 +1334,7 @@ static DN_UTCore DN_TST_BaseArray() DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 15, 2, DN_ArrayErase_Stable); int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; DN_UT_Assert(&result, erase.items_erased == 0); - DN_UT_Assert(&result, erase.it_index == 9); + DN_UT_Assert(&result, erase.it_index == 10); DN_UT_Assert(&result, size == 10); DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0); } diff --git a/Source/Extra/dn_tests_main.cpp b/Source/Extra/dn_tests_main.cpp index 49af0bd..5dad454 100644 --- a/Source/Extra/dn_tests_main.cpp +++ b/Source/Extra/dn_tests_main.cpp @@ -35,7 +35,7 @@ DN_MSVC_WARNING_PUSH DN_MSVC_WARNING_DISABLE(6262) // Function uses '29804' bytes of stack. Consider moving some data to heap. int main(int, char**) { - DN_Core dn = {}; + DN_Core dn = {}; DN_Init(&dn, DN_InitFlags_LogAllFeatures | DN_InitFlags_OS | DN_InitFlags_ThreadContext, DN_TCInitArgsDefault()); DN_TST_RunSuite(DN_TSTPrint_Yes); return 0; diff --git a/Source/OS/dn_os.cpp b/Source/OS/dn_os.cpp index 94ac11a..c4916e9 100644 --- a/Source/OS/dn_os.cpp +++ b/Source/OS/dn_os.cpp @@ -738,8 +738,8 @@ DN_API DN_OSExecResult DN_OS_ExecOrAbort(DN_Str8Slice cmd_line, DN_OSExecArgs *a // NOTE: DN_OSThread static void DN_OS_ThreadExecute_(void *user_context) { - DN_OSThread *thread = DN_Cast(DN_OSThread *) user_context; - DN_TCInitFromMemFuncs(&thread->context, thread->thread_id, DN_TCInitArgsDefault(), DN_MemFuncsDefault()); + DN_OSThread *thread = DN_Cast(DN_OSThread *) user_context; + DN_TCInitFromMemFuncs(&thread->context, thread->thread_id, thread->tc_init_args, DN_MemFuncsDefault()); DN_TCEquip(&thread->context); if (thread->is_lane_set) { DN_OS_TCThreadLaneEquip(thread->lane); @@ -801,7 +801,7 @@ DN_API void DN_OS_ThreadLaneSync(DN_OSThreadLane *lane, void **ptr_to_share) DN_OS_BarrierWait(&lane->barrier); // NOTE: Ensure the reading lanes have completed the read } -DN_API DN_V2USize DN_OS_ThreadLaneRange(DN_OSThreadLane *lane, DN_USize values_count) +DN_API DN_V2USize DN_OS_ThreadLaneRange(DN_OSThreadLane const *lane, DN_USize values_count) { DN_USize values_per_thread = values_count / lane->count; DN_USize rem_values = values_count % lane->count; @@ -822,6 +822,44 @@ DN_API DN_V2USize DN_OS_ThreadLaneRange(DN_OSThreadLane *lane, DN_USize values_c return result; } +DN_API DN_OSThreadLaneway DN_OS_ThreadLanewayFromArgs(DN_OSThread* threads, DN_USize threads_count, DN_UPtr* shared_mem) +{ + DN_OSThreadLaneway result = {}; + result.threads = threads; + result.threads_count = threads_count; + result.shared_mem = shared_mem; + result.barrier = DN_OS_BarrierInit(DN_Cast(DN_U32) result.threads_count); + return result; +} + +DN_API DN_OSThreadLaneway DN_OS_ThreadLanewayFromArena(DN_USize threads_count, DN_Arena* arena) +{ + DN_U64 mem_p = DN_MemListPos(arena->mem); + DN_OSThreadLaneway result = {}; + DN_OSThread* threads = DN_ArenaNewArray(arena, DN_OSThread, threads_count, DN_ZMem_No); + DN_UPtr* shared_mem = DN_ArenaNewZ(arena, DN_UPtr); + if (threads && shared_mem) + result = DN_OS_ThreadLanewayFromArgs(threads, threads_count, shared_mem); + else + DN_MemListPopTo(arena->mem, mem_p); + return result; +} + +DN_API void DN_OS_ThreadLanewayDispatch(DN_OSThreadLaneway *laneway, DN_OSThreadFunc *entry_point, DN_TCInitArgs tc_init_args, void *user_context) +{ + for (DN_ForItSize(it, DN_OSThread, laneway->threads, laneway->threads_count)) { + DN_OSThreadLane lane = DN_OS_ThreadLaneInit(it.index, laneway->threads_count, laneway->barrier, laneway->shared_mem); + DN_OS_ThreadInit(it.data, entry_point, &lane, tc_init_args, user_context); + } +} + +DN_API void DN_OS_ThreadLanewayJoin(DN_OSThreadLaneway *laneway, DN_TCDeinitArenas deinit_arenas) +{ + for (DN_ForItSize(it, DN_OSThread, laneway->threads, laneway->threads_count)) + DN_OS_ThreadJoin(it.data, deinit_arenas); + DN_OS_BarrierDeinit(&laneway->barrier); +} + DN_API DN_OSThreadLane *DN_OS_TCThreadLane() { DN_TCCore *tc = DN_TCGet(); @@ -1269,7 +1307,7 @@ DN_API DN_StackTrace DN_StackTraceFromAllocator(DN_Allocator allocator, DN_U16 l DN_Memcpy(result.base_addr, raw_frames, raw_frames_count * sizeof(raw_frames[0])); #else (void)limit; - (void)arena; + (void)allocator; #endif return result; } diff --git a/Source/OS/dn_os.h b/Source/OS/dn_os.h index f641817..c92b16a 100644 --- a/Source/OS/dn_os.h +++ b/Source/OS/dn_os.h @@ -207,6 +207,14 @@ struct DN_OSThreadLane void* shared_mem; }; +struct DN_OSThreadLaneway +{ + DN_OSThread* threads; + DN_USize threads_count; + DN_UPtr* shared_mem; + DN_OSBarrier barrier; +}; + struct DN_OSThread { DN_Str8x64 name; @@ -218,6 +226,7 @@ struct DN_OSThread void *user_context; DN_OSThreadFunc *func; DN_OSSemaphore init_semaphore; + DN_TCInitArgs tc_init_args; }; // NOTE: DN_OSHttp @@ -422,14 +431,79 @@ DN_API bool DN_OS_ConditionVariableWaitUntil (D DN_API void DN_OS_ConditionVariableSignal (DN_OSConditionVariable *cv); DN_API void DN_OS_ConditionVariableBroadcast (DN_OSConditionVariable *cv); -DN_API bool DN_OS_ThreadInit (DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, void *user_context); +DN_API bool DN_OS_ThreadInit (DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, DN_TCInitArgs tc_init_args, void *user_context); DN_API bool DN_OS_ThreadJoin (DN_OSThread *thread, DN_TCDeinitArenas deinit_arenas); DN_API DN_U32 DN_OS_ThreadID (); DN_API void DN_OS_ThreadSetNameFmt (char const *fmt, ...); +// NOTE: Thread lanes provide an abstraction to represent the concept of programming a CPU like a +// GPU, e.g. SIMT (Single Instruction Multiple Threads). The lane terminology is popularised by Ryan +// Fleury. SIMT is formally defined as +// +// Threads are grouped into warps/wavefronts (typically 32 or 64 threads) that execute the same +// instruction in lockstep, but each thread operates on different data and maintains its own state +// +// The individual threads in a wavefront on the CPU side are colloquially dubbed "lanes" and a +// thread lane here contains the necessary state to facilitate this such as the current index in the +// wavefront and synchronisation primitives to coordinate the different lanes together. +// +// The idea is to write code in a single-threaded manner (linear execution) but across multiple +// threads so that the default is all execution paths are inherently multi-threaded by default. Opt +// out of parallelism instead of opt in. This optimises for the trend of core counts increasing +// whilst clock counts remain static. +// +// A laneway is a helper function to initialise the number of requested OS threads/lanes upfront and +// setup the required synchronisation primitives. It can then be dispatched all the threads which +// start executing the `entry_point` in parallel. +// +// API +// DN_OS_ThreadLaneSync +// A blocking call to synchronise the program-counter of all other lanes in the laneway to this +// function call invocation (using an OS barrier). Optionally pass in the pointer to a pointer +// `ptr_to_share` to broadcast the pointer from one lanes to the others. The lane that wishes +// to broadcast the pointer must have a non-null pointer, all other lanes must pass in a +// non-null pointer. A typical use case might look like: +/* + DN_OSThreadLane *lane = DN_OS_TCThreadLane(); // Get lane from current (t)hread (c)context + + // NOTE: Allocate buffer in lane 0 + DN_U8 *buffer = nullptr; + if (lane->index == 0) + buffer = DN_ArenaNewArray(DN_TCMainArena(), DN_U8, DN_Gigabytes(1), DN_ZMem_No); + + // NOTE: Lane 0 broadcasts the `buffer` pointer to lane 1..N + DN_OS_ThreadLaneSync(lane, &buffer); + + // NOTE: We use LaneRange to divide the buffer into equal sized chunks that each lane can + // write into without clobbering over each other. + DN_V2USize range = DN_OS_ThreadLaneRange(lane, DN_Gigabytes(1)); + for (DN_USize index = range.begin; index < range.end; index++) { buffer[index] = index; } +*/ +// In this example, lane 0 will allocate a 1GiB buffer pass in a `buffer` to +// DN_OS_ThreadLaneSync` that is non-null. Lanes 1->N will skip the branch (because their lanes +// indexes are 1..N) and invoke `DN_OS_ThreadLaneSync` with a nullptr `buffer`. After the +// blocking call is complete, lanes 0->N will now have synchronised the `buffer` pointer and all +// lanes point to the 1GiB range allocated in lane 0's allocator. +// +// Additionally we demonstrate `DN_OS_ThreadLaneRange` which does math behind the scenes to +// divide the buffer up and assign each lane their own indices in the buffer that they can work +// on in parallel without clobbering each others work. +// +// DN_OS_ThreadLaneRange +// Calculates the range of values the current lane in the laneway should execute. For example if +// you have 128 items and 16 threads each lane will receive the following `DN_V2USize` range: +// Lane 0 => [0, 8) +// Lane 1 => [8, 16) +// ... +// Lane 16 => [120, 128) DN_API DN_OSThreadLane DN_OS_ThreadLaneInit (DN_USize index, DN_USize thread_count, DN_OSBarrier barrier, DN_UPtr *share_mem); DN_API void DN_OS_ThreadLaneSync (DN_OSThreadLane *lane, void **ptr_to_share); -DN_API DN_V2USize DN_OS_ThreadLaneRange (DN_OSThreadLane *lane, DN_USize values_count); +DN_API DN_V2USize DN_OS_ThreadLaneRange (DN_OSThreadLane const *lane, DN_USize values_count); + +DN_API DN_OSThreadLaneway DN_OS_ThreadLanewayFromArgs (DN_OSThread* threads, DN_USize threads_count, DN_UPtr* shared_mem); +DN_API DN_OSThreadLaneway DN_OS_ThreadLanewayFromArena (DN_USize threads_count, DN_Arena* arena); +DN_API void DN_OS_ThreadLanewayDispatch (DN_OSThreadLaneway *laneway, DN_OSThreadFunc *entry_point, DN_TCInitArgs tc_init_args, void *user_context); +DN_API void DN_OS_ThreadLanewayJoin (DN_OSThreadLaneway *laneway, DN_TCDeinitArenas deinit_arenas); DN_API DN_OSThreadLane* DN_OS_TCThreadLane (); DN_API void DN_OS_TCThreadLaneSync (void **ptr_to_share); diff --git a/Source/OS/dn_os_posix.cpp b/Source/OS/dn_os_posix.cpp index 715e6d6..cd8967f 100644 --- a/Source/OS/dn_os_posix.cpp +++ b/Source/OS/dn_os_posix.cpp @@ -228,7 +228,7 @@ DN_API bool DN_OS_SetEnvVar(DN_Str8 name, DN_Str8 value) DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path) { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); DN_OSDiskSpace result = {}; DN_Str8 path_z_terminated = DN_Str8FromStr8Arena(path, &scratch.arena); struct statvfs info = {}; @@ -387,7 +387,7 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink result = (bytes_written == stat_existing.st_size); if (!result) { int error_code = errno; - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); DN_Str8 file_size_str8 = DN_Str8FromByteCount(scratch.arena, stat_existing.st_size, DN_ByteCountType_Auto); DN_Str8 bytes_written_str8 = DN_Str8FromByteCount(scratch.arena, bytes_written, DN_ByteCountType_Auto); DN_rrSinkAppendF(error, @@ -517,8 +517,8 @@ DN_API DN_OSFileRead DN_OS_FileRead(DN_OSFile *file, void *buffer, DN_USize size result.bytes_read = fread(buffer, 1, size, DN_Cast(FILE *) file->handle); if (feof(DN_Cast(FILE*)file->handle)) { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); - DN_Str8x32 buffer_size_str8 = DN_ByteCountStr8x32(size); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); + DN_Str8x32 buffer_size_str8 = DN_Str8x32FromByteCountU64Auto(size); DN_ErrSinkAppendF(err, 1, "Failed to read %S from file", buffer_size_str8); DN_TCScratchEnd(&scratch); return result; @@ -536,8 +536,8 @@ DN_API bool DN_OS_FileWritePtr(DN_OSFile *file, void const *buffer, DN_USize siz fwrite(buffer, DN_Cast(DN_USize) size, 1 /*count*/, DN_Cast(FILE *) file->handle) == 1 /*count*/; if (!result) { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); - DN_Str8x32 buffer_size_str8 = DN_ByteCountStr8x32(size); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); + DN_Str8x32 buffer_size_str8 = DN_Str8x32FromByteCountU64Auto(size); DN_ErrSinkAppendF(err, 1, "Failed to write buffer (%s) to file handle", DN_Str8PrintFmt(buffer_size_str8)); DN_TCScratchEnd(&scratch); } @@ -627,7 +627,7 @@ DN_API bool DN_OS_PathIsDir(DN_Str8 path) DN_API bool DN_OS_PathMakeDir(DN_Str8 path) { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); bool result = true; // TODO(doyle): Implement this without using the path indexes, it's not @@ -793,7 +793,7 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, // NOTE: Read the data from the read end of the pipe if (result.os_error_code == 0) { - DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1); + DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1); if (arena && handle.stdout_read) { char buffer[4096]; DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena); @@ -805,7 +805,7 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, DN_Str8BuilderAppendF(&builder, "%.*s", bytes_read, buffer); } - result.stdout_text = DN_Str8BuilderBuild(&builder, arena); + result.stdout_text = DN_Str8FromStr8BuilderArena(&builder, arena); } if (arena && handle.stderr_read) { @@ -819,7 +819,7 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, DN_Str8BuilderAppendF(&builder, "%.*s", bytes_read, buffer); } - result.stderr_text = DN_Str8BuilderBuild(&builder, arena); + result.stderr_text = DN_Str8FromStr8BuilderArena(&builder, arena); } DN_TCScratchEnd(&scratch); } @@ -842,7 +842,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, if (cmd_line.count == 0) return result; - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); DN_DEFER { DN_TCScratchEnd(&scratch); }; DN_Str8 cmd_rendered = DN_Str8SliceRender(cmd_line, DN_Str8Lit(" "), &scratch.arena); int stdout_pipe[DN_OSPipeType__Count] = {}; @@ -1286,7 +1286,7 @@ static void *DN_OS_ThreadFunc_(void *user_context) return nullptr; } -DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, void *user_context) +DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, DN_TCInitArgs tc_init_args, void *user_context) { bool result = false; if (!thread) @@ -1296,6 +1296,7 @@ DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSTh thread->user_context = user_context; thread->init_semaphore = DN_OS_SemaphoreInit(0 /*initial_count*/); thread->lane = *lane; + thread->tc_init_args = tc_init_args; // TODO(doyle): Check if semaphore is valid // NOTE: pthread_t is essentially the thread ID. In Windows, the handle and @@ -1370,7 +1371,7 @@ DN_API void DN_OS_PosixThreadSetName(DN_Str8 name) #if defined(DN_PLATFORM_EMSCRIPTEN) (void)name; #else - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); DN_Str8 copy = DN_Str8FromStr8Arena(name, &scratch.arena); pthread_t thread = pthread_self(); pthread_setname_np(thread, (char *)copy.data); @@ -1394,7 +1395,7 @@ DN_API DN_OSPosixProcSelfStatus DN_OS_PosixProcSelfStatus() DN_OSFile file = DN_OS_FileOpen(DN_Str8Lit("/proc/self/status"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_Read, nullptr); if (!file.error) { - DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); + DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); char buf[256]; DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena); for (;;) { @@ -1408,7 +1409,7 @@ DN_API DN_OSPosixProcSelfStatus DN_OS_PosixProcSelfStatus() DN_Str8 const PID = DN_Str8Lit("Pid:"); DN_Str8 const VM_PEAK = DN_Str8Lit("VmPeak:"); DN_Str8 const VM_SIZE = DN_Str8Lit("VmSize:"); - DN_Str8 status_buf = DN_Str8BuilderBuild(&builder, &scratch.arena); + DN_Str8 status_buf = DN_Str8FromStr8BuilderArena(&builder, &scratch.arena); DN_Str8SplitResult lines = DN_Str8SplitArena(status_buf, DN_Str8Lit("\n"), DN_Str8SplitFlags_ExcludeEmptyStrings, &scratch.arena); for (DN_ForItSize(line_it, DN_Str8, lines.data, lines.count)) { @@ -1535,7 +1536,7 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response, response->builder.arena = response->scratch_arena.mem ? &response->scratch_arena : &response->tmp_arena; DN_Arena *scratch = &response->scratch_arena; - DN_TCScratch scratch_ = DN_TCScratchBegin(&arena, 1); + DN_TCScratch scratch_ = DN_TCScratchBeginArena(&arena, 1); DN_DEFER { DN_TCScratchEnd(&scratch_); }; if (!scratch) scratch = &scratch_.arena; diff --git a/Source/OS/dn_os_w32.cpp b/Source/OS/dn_os_w32.cpp index 8808894..1c9f7e1 100644 --- a/Source/OS/dn_os_w32.cpp +++ b/Source/OS/dn_os_w32.cpp @@ -1239,7 +1239,7 @@ static DWORD __stdcall DN_OS_ThreadFunc_(void *user_context) return 0; } -DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, void *user_context) +DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, DN_TCInitArgs tc_init_args, void *user_context) { bool result = false; if (!thread) @@ -1248,6 +1248,7 @@ DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSTh thread->func = func; thread->user_context = user_context; thread->init_semaphore = DN_OS_SemaphoreInit(0 /*initial_count*/); + thread->tc_init_args = tc_init_args; if (lane) { thread->is_lane_set = true; thread->lane = *lane; diff --git a/Source/dn.h b/Source/dn.h index 9d6a1da..e473791 100644 --- a/Source/dn.h +++ b/Source/dn.h @@ -176,7 +176,7 @@ struct DN_Core DN_USize mem_allocs_frame; DN_LeakTracker leak; - DN_U32 log_level_to_show_from; + DN_LogType log_level_to_show_from; DN_LogPrintFunc* print_func; void* print_func_context;