Get latest changes from Primitive Indexer"

This commit is contained in:
2026-07-07 23:09:44 +10:00
parent 234fd9e302
commit 378349ebbf
6 changed files with 1175 additions and 489 deletions
+281 -114
View File
@@ -1,4 +1,4 @@
// Generated by the DN single header generator 2026-07-05 23:26:32 // Generated by the DN single header generator 2026-07-07 23:09:14
// DN: Single header generator commented out => #if defined(_CLANGD) // DN: Single header generator commented out => #if defined(_CLANGD)
// #define DN_WITH_TESTS 1 // #define DN_WITH_TESTS 1
@@ -548,24 +548,24 @@ DN_API DN_CPUReport DN_CPUGetReport()
return result; return result;
} }
DN_API void DN_TicketMutex_Begin(DN_TicketMutex *mutex) DN_API void DN_TicketMutexBegin(DN_TicketMutex *mutex)
{ {
DN_UInt ticket = DN_AtomicAddU32(&mutex->ticket, 1); DN_UInt ticket = DN_AtomicAddU32(&mutex->ticket, 1);
DN_TicketMutex_BeginTicket(mutex, ticket); DN_TicketMutexBeginTicket(mutex, ticket);
} }
DN_API void DN_TicketMutex_End(DN_TicketMutex *mutex) DN_API void DN_TicketMutexEnd(DN_TicketMutex *mutex)
{ {
DN_AtomicAddU32(&mutex->serving, 1); DN_AtomicAddU32(&mutex->serving, 1);
} }
DN_API DN_UInt DN_TicketMutex_MakeTicket(DN_TicketMutex *mutex) DN_API DN_UInt DN_TicketMutexMakeTicket(DN_TicketMutex *mutex)
{ {
DN_UInt result = DN_AtomicAddU32(&mutex->ticket, 1); DN_UInt result = DN_AtomicAddU32(&mutex->ticket, 1);
return result; return result;
} }
DN_API void DN_TicketMutex_BeginTicket(DN_TicketMutex const *mutex, DN_UInt ticket) DN_API void DN_TicketMutexBeginTicket(DN_TicketMutex const *mutex, DN_UInt ticket)
{ {
DN_AssertF(mutex->serving <= ticket, DN_AssertF(mutex->serving <= ticket,
"Mutex skipped ticket? Was ticket generated by the correct mutex via MakeTicket? ticket = %u, " "Mutex skipped ticket? Was ticket generated by the correct mutex via MakeTicket? ticket = %u, "
@@ -578,7 +578,7 @@ DN_API void DN_TicketMutex_BeginTicket(DN_TicketMutex const *mutex, DN_UInt tick
} }
} }
DN_API bool DN_TicketMutex_CanLock(DN_TicketMutex const *mutex, DN_UInt ticket) DN_API bool DN_TicketMutexCanLock(DN_TicketMutex const *mutex, DN_UInt ticket)
{ {
bool result = (ticket == mutex->serving); bool result = (ticket == mutex->serving);
return result; return result;
@@ -1768,6 +1768,12 @@ DN_API void DN_ArenaDeinit(DN_Arena *arena)
DN_MemListDeinit(arena->mem); DN_MemListDeinit(arena->mem);
} }
DN_API bool DN_ArenaOwnsPtr(DN_Arena const *arena, void *ptr)
{
bool result = DN_MemListOwnsPtr(arena->mem, ptr);
return result;
}
DN_API DN_Pool DN_PoolFromArena(DN_Arena *arena, DN_U8 align) DN_API DN_Pool DN_PoolFromArena(DN_Arena *arena, DN_U8 align)
{ {
DN_Pool result = {}; DN_Pool result = {};
@@ -5058,7 +5064,6 @@ DN_API DN_U8x16 DN_U8x16FromPtrHex32(char const *hex, DN_USize hex_count)
{ {
DN_U8x16 result = {}; DN_U8x16 result = {};
DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count)); DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count));
DN_Assert(hex_trimmed.count / 2 == sizeof result.data);
DN_USize bytes_written = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, sizeof result.data); DN_USize bytes_written = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, sizeof result.data);
DN_Assert(bytes_written == sizeof result.data); DN_Assert(bytes_written == sizeof result.data);
return result; return result;
@@ -5068,7 +5073,6 @@ DN_API DN_U8x32 DN_U8x32FromPtrHex64(char const *hex, DN_USize hex_count)
{ {
DN_U8x32 result = {}; DN_U8x32 result = {};
DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count)); DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count));
DN_Assert(hex_trimmed.count / 2 == sizeof result.data);
DN_USize bytes_written = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, sizeof result.data); DN_USize bytes_written = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, sizeof result.data);
DN_Assert(bytes_written == sizeof result.data); DN_Assert(bytes_written == sizeof result.data);
return result; return result;
@@ -8094,6 +8098,7 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a,
return result; return result;
} }
typedef struct DN_ArrayFindEqMemcmpContext_ DN_ArrayFindEqMemcmpContext_;
struct DN_ArrayFindEqMemcmpContext_ struct DN_ArrayFindEqMemcmpContext_
{ {
DN_USize elem_size; DN_USize elem_size;
@@ -9629,6 +9634,7 @@ DN_API void DN_TestVerifyBytesF(DN_TestCore *test, DN_CallSite call_site, DN_Str
#if defined(DN_PLATFORM_WIN32) && defined(DN_COMPILER_MSVC) #if defined(DN_PLATFORM_WIN32) && defined(DN_COMPILER_MSVC)
// NOTE: Taken from MSDN __cpuid example implementation // NOTE: Taken from MSDN __cpuid example implementation
// https://learn.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-170 // https://learn.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-170
typedef struct DN_RefImplCPUReport DN_RefImplCPUReport;
struct DN_RefImplCPUReport { struct DN_RefImplCPUReport {
unsigned int nIds_ = 0; unsigned int nIds_ = 0;
unsigned int nExIds_ = 0; unsigned int nExIds_ = 0;
@@ -9791,22 +9797,22 @@ DN_API DN_TestCore DN_TestSuite(DN_Arena *arena_)
{ {
for (DN_TestScopeF(&result, "[TicketMutex] Start and stop")) { for (DN_TestScopeF(&result, "[TicketMutex] Start and stop")) {
DN_TicketMutex mutex = {}; DN_TicketMutex mutex = {};
DN_TicketMutex_Begin(&mutex); DN_TicketMutexBegin(&mutex);
DN_TicketMutex_End(&mutex); DN_TicketMutexEnd(&mutex);
DN_TestVerifyUSizeEq(&result, mutex.ticket, mutex.serving); DN_TestVerifyUSizeEq(&result, mutex.ticket, mutex.serving);
} }
for (DN_TestScopeF(&result, "[TicketMutex] Start and stop w/ advanced API")) { for (DN_TestScopeF(&result, "[TicketMutex] Start and stop w/ advanced API")) {
DN_TicketMutex mutex = {}; DN_TicketMutex mutex = {};
unsigned int ticket_a = DN_TicketMutex_MakeTicket(&mutex); DN_UInt ticket_a = DN_TicketMutexMakeTicket(&mutex);
unsigned int ticket_b = DN_TicketMutex_MakeTicket(&mutex); DN_UInt ticket_b = DN_TicketMutexMakeTicket(&mutex);
DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutex_CanLock(&mutex, ticket_b) == false); DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutexCanLock(&mutex, ticket_b) == false);
DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutex_CanLock(&mutex, ticket_a) == true); DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutexCanLock(&mutex, ticket_a) == true);
DN_TicketMutex_BeginTicket(&mutex, ticket_a); DN_TicketMutexBeginTicket(&mutex, ticket_a);
DN_TicketMutex_End(&mutex); DN_TicketMutexEnd(&mutex);
DN_TicketMutex_BeginTicket(&mutex, ticket_b); DN_TicketMutexBeginTicket(&mutex, ticket_b);
DN_TicketMutex_End(&mutex); DN_TicketMutexEnd(&mutex);
DN_TestVerifyUSizeEq(&result, mutex.ticket, mutex.serving); DN_TestVerifyUSizeEq(&result, mutex.ticket, mutex.serving);
DN_TestVerifyUSizeEq(&result, mutex.ticket, ticket_b + 1); DN_TestVerifyUSizeEq(&result, mutex.ticket, ticket_b + 1);
@@ -11289,7 +11295,7 @@ DN_API void DN_LeakTrackAlloc_(DN_LeakTracker *leak, void *ptr, DN_USize size, b
if (!ptr) if (!ptr)
return; return;
DN_TicketMutex_Begin(&leak->alloc_table_mutex); DN_TicketMutexBegin(&leak->alloc_table_mutex);
DN_Str8 stack_trace = DN_Str8FromStackTraceNowHeap(128, 3 /*skip*/); DN_Str8 stack_trace = DN_Str8FromStackTraceNowHeap(128, 3 /*skip*/);
DN_HTable* alloc_table = &leak->alloc_table; DN_HTable* alloc_table = &leak->alloc_table;
@@ -11335,7 +11341,7 @@ DN_API void DN_LeakTrackAlloc_(DN_LeakTracker *leak, void *ptr, DN_USize size, b
alloc->stack_trace = stack_trace; alloc->stack_trace = stack_trace;
alloc->flags |= leak_permitted ? DN_LeakAllocFlag_LeakPermitted : 0; alloc->flags |= leak_permitted ? DN_LeakAllocFlag_LeakPermitted : 0;
leak->alloc_table_bytes_allocated_for_stack_traces += alloc->stack_trace.count; leak->alloc_table_bytes_allocated_for_stack_traces += alloc->stack_trace.count;
DN_TicketMutex_End(&leak->alloc_table_mutex); DN_TicketMutexEnd(&leak->alloc_table_mutex);
} }
DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr) DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
@@ -11343,7 +11349,7 @@ DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
if (!ptr) if (!ptr)
return; return;
DN_TicketMutex_Begin(&leak->alloc_table_mutex); DN_TicketMutexBegin(&leak->alloc_table_mutex);
DN_Str8 stack_trace = DN_Str8FromStackTraceNowHeap(128, 3 /*skip*/); DN_Str8 stack_trace = DN_Str8FromStackTraceNowHeap(128, 3 /*skip*/);
DN_HTable* alloc_table = &leak->alloc_table; DN_HTable* alloc_table = &leak->alloc_table;
@@ -11384,7 +11390,7 @@ DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
alloc->flags |= DN_LeakAllocFlag_Freed; alloc->flags |= DN_LeakAllocFlag_Freed;
alloc->freed_stack_trace = stack_trace; alloc->freed_stack_trace = stack_trace;
leak->alloc_table_bytes_allocated_for_stack_traces += alloc->freed_stack_trace.count; leak->alloc_table_bytes_allocated_for_stack_traces += alloc->freed_stack_trace.count;
DN_TicketMutex_End(&leak->alloc_table_mutex); DN_TicketMutexEnd(&leak->alloc_table_mutex);
} }
DN_API void DN_LeakDump_(DN_LeakTracker *leak) DN_API void DN_LeakDump_(DN_LeakTracker *leak)
@@ -11446,52 +11452,150 @@ DN_API DN_Str8 DN_OS_Str8FromStr8BuilderHeap(DN_Str8Builder const *builder)
DN_API void DN_OS_LogPrint(DN_LogTypeParam type, void *user_data, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, va_list args) DN_API void DN_OS_LogPrint(DN_LogTypeParam type, void *user_data, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, va_list args)
{ {
DN_Assert(user_data);
DN_OSCore *os = DN_Cast(DN_OSCore *)user_data; DN_OSCore *os = DN_Cast(DN_OSCore *)user_data;
DN_OSLogger *logger = &os->logger;
DN_OS_LoggerFV(logger, type, call_site, flags, fmt, args);
}
// NOTE: Open log file for appending if requested DN_API DN_Str8 DN_OS_LoggerGetRotateFilePath(DN_Str8 base_file_path, DN_Arena *arena, DN_USize rotate_index)
DN_TicketMutex_Begin(&os->log_file_mutex); {
if (os->log_to_file && !os->log_file.handle && !os->log_file.error) { DN_Str8 result = {};
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); if (rotate_index == 0)
DN_Str8 exe_dir = DN_OS_EXEDir(&scratch.arena); result = DN_OS_PathFmtArena(arena, "%.*s", DN_Str8PrintFmt(base_file_path));
DN_Str8 log_path = DN_OS_PathF(&scratch.arena, "%.*s/dn.log", DN_Str8PrintFmt(exe_dir)); else
os->log_file = DN_OS_FileOpen(log_path, DN_OSFileOpen_CreateAlways, DN_OSFileAccess_AppendOnly, nullptr); result = DN_OS_PathFmtArena(arena, "%.*s.%zu", DN_Str8PrintFmt(base_file_path), rotate_index);
DN_TCScratchEnd(&scratch); return result;
}
static void DN_OS_LoggerSetFilePathNoMutex_(DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path)
{
if (logger->file_path.data) {
DN_AssertF(DN_MemListOwnsPtr(pool->arena->mem, logger->file_path.data),
"If there's a pre-existing file path set in the logger, it must be deallocated by "
" the caller and cleared. If it has been previously allocated with the exact same "
" pool was allocated with the same pool then we will deallocate it for you.");
DN_PoolDealloc(pool, logger->file_path.data);
logger->file_path = {};
} }
DN_TicketMutex_End(&os->log_file_mutex); DN_OS_FileClose(&logger->file);
logger->file_path = DN_OS_PathFmtPool(pool, "%.*s", DN_Str8PrintFmt(file_path));
// NOTE: Clear the sticky file error flag if it was set
logger->flags &= ~DN_OSLoggerFlags_FileError;
}
DN_API void DN_OS_LoggerSetFilePath(DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path)
{
DN_TicketMutexBegin(&logger->file_mutex);
DN_OS_LoggerSetFilePathNoMutex_(logger, pool, file_path);
DN_TicketMutexEnd(&logger->file_mutex);
}
static void DN_OS_DoLogFileSetupAndRotation_(DN_OSLogger *logger)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
DN_Str8 error = {};
DN_TicketMutexBegin(&logger->file_mutex);
if (logger->flags & DN_OSLoggerFlags_File) {
// NOTE: Set a default file path to log to if it's not been set yet
if (logger->file_path.count == 0) {
DN_Str8 exe_dir = DN_OS_EXEDir(&scratch.arena);
DN_Str8 default_file_path = DN_OS_PathFmtArena(&scratch.arena, "%.*s/dn.log", DN_Str8PrintFmt(exe_dir));
DN_OS_LoggerSetFilePathNoMutex_(logger, DN_TCMainPool(), default_file_path);
}
// NOTE Rotate the log file if the criteria is met
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError) && logger->rotate_every_n_bytes && logger->rotate_count) {
DN_Assert(logger->file_path.count);
DN_Assert(logger->rotate_every_n_bytes > 0);
DN_OSPathInfo file_info = DN_OS_PathInfo(logger->file_path);
bool needs_rotate = file_info.size >= logger->rotate_every_n_bytes;
if (needs_rotate) {
DN_OS_FileClose(&logger->file);
// NOTE: Loop through all the rotated log files from [rotate_count-1..1]. The rotated log
// file at `rotate_count-1` gets deleted and `rotate_count-2` gets moved into
// `rotate_count-1` and so forth
for (DN_USize offset = 0; offset < (logger->rotate_count - 1); offset++) {
DN_USize const file_index = logger->rotate_count - (offset + 1);
DN_Str8 file_path = DN_OS_LoggerGetRotateFilePath(logger->file_path, &scratch.arena, file_index);
DN_Str8 prev_file_path = DN_OS_LoggerGetRotateFilePath(logger->file_path, &scratch.arena, file_index - 1);
DN_OS_FileMove(prev_file_path, file_path, true, nullptr);
}
}
// NOTE: After rotating, check the file size of the log file we will write to again. If the
// file size is still greater than the rotate size, then there was an error when we
// attempted to rotate the logs. Set the sticky file flag error to disable to logger and
// inform the user.
if (needs_rotate) {
DN_OSPathInfo recheck_file_info = DN_OS_PathInfo(logger->file_path);
if (recheck_file_info.size >= logger->rotate_every_n_bytes) {
logger->flags |= DN_OSLoggerFlags_FileError;
error = DN_Str8FromFmtArena(&scratch.arena, "Rotating of log files failed at (%.*s). Logging to disk is disabled", DN_Str8PrintFmt(logger->file_path));
}
}
}
// NOTE: Open the file requested by the logger if it hasn't been opened yet
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError)) {
if (!logger->file.handle && !logger->file.error) {
DN_OSPathInfo file_path_info = DN_OS_PathInfo(logger->file_path);
if (file_path_info.exists && file_path_info.type != DN_OSPathInfoType_File) {
logger->flags |= DN_OSLoggerFlags_FileError;
error = DN_Str8FromFmtArena(&scratch.arena, "File path to log to (%.*s) exists but is not a writable file. Logging to disk is disabled.", DN_Str8PrintFmt(logger->file_path));
}
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError))
logger->file = DN_OS_FileOpen(logger->file_path, DN_OSFileOpen_OpenAlways, DN_OSFileAccess_AppendOnly, nullptr);
}
}
// NOTE: Set the sticky error flag on the file if opening failed. The sticky flag ensures we
// only notify the user once of a file open failure per unique base file path
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError)) {
if (logger->file.error) {
logger->flags |= DN_OSLoggerFlags_FileError;
error = DN_Str8FromFmtArena(&scratch.arena, "Failed to open file (%.*s) for logging. Logging to disk is disabled", DN_Str8PrintFmt(logger->file_path));
}
}
}
DN_TicketMutexEnd(&logger->file_mutex);
// NOTE: Error is logged outside of the mutex since logging will recurse back into the OS logger
if (error.count)
DN_LogWarningF("%.*s", DN_Str8PrintFmt(error));
DN_TCScratchEnd(&scratch);
}
DN_API void DN_OS_LoggerFV(DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, va_list args)
{
DN_OS_DoLogFileSetupAndRotation_(logger);
bool print_prefix = DN_BitIsNotSet(flags, DN_LogFlags_NoPrefix); bool print_prefix = DN_BitIsNotSet(flags, DN_LogFlags_NoPrefix);
char prefix_buffer[128] = {}; char prefix_buffer[128] = {};
DN_LogPrefixSize prefix_size = {}; DN_LogPrefixSize prefix_size = {};
char prefix_colour_buffer[128] = {};
DN_LogPrefixSize prefix_colour_size = {};
if (print_prefix) { if (print_prefix) {
DN_LogStyle style = {}; // NOTE: Generate 2 variants of the style (colour and colour-less) for printing the prefix of
if (!os->log_no_colour) { // the log line
style.colour = true; DN_LogStyle style_colour = {};
style.bold = DN_LogBold_Yes; style_colour.bold = DN_LogBold_Yes;
style_colour.colour = true;
if (type.is_u32_enum) { if (type.is_u32_enum) {
switch (type.u32) { switch (type.u32) {
case DN_LogType_Debug: { case DN_LogType_Debug: style_colour.colour = false; style_colour.bold = DN_LogBold_No; break;
case DN_LogType_Info: style_colour.g = 0x87; style_colour.b = 0xff; break;
case DN_LogType_Warning: style_colour.r = 0xff; style_colour.g = 0xff; break;
case DN_LogType_Error: style_colour.r = 0xff; break;
}
}
DN_LogStyle style = style_colour;
style.colour = false; style.colour = false;
style.bold = DN_LogBold_No;
} break;
case DN_LogType_Info: {
style.g = 0x87;
style.b = 0xff;
} break;
case DN_LogType_Warning: {
style.r = 0xff;
style.g = 0xff;
} break;
case DN_LogType_Error: {
style.r = 0xff;
} break;
}
}
}
// NOTE: Build the log prefix
DN_Date os_date = DN_OS_DateLocalTimeNow(); DN_Date os_date = DN_OS_DateLocalTimeNow();
DN_LogDate log_date = {}; DN_LogDate log_date = {};
log_date.year = os_date.year; log_date.year = os_date.year;
@@ -11500,35 +11604,50 @@ DN_API void DN_OS_LogPrint(DN_LogTypeParam type, void *user_data, DN_CallSite ca
log_date.hour = os_date.hour; log_date.hour = os_date.hour;
log_date.minute = os_date.minutes; log_date.minute = os_date.minutes;
log_date.second = os_date.seconds; log_date.second = os_date.seconds;
prefix_size = DN_LogMakePrefix(style, type, call_site, log_date, prefix_buffer, sizeof(prefix_buffer)); prefix_size = DN_LogMakePrefix(style, type, call_site, log_date, prefix_buffer, DN_ArrayCountU(prefix_buffer));
prefix_colour_size = DN_LogMakePrefix(style_colour, type, call_site, log_date, prefix_colour_buffer, DN_ArrayCountU(prefix_colour_buffer));
} }
// NOTE: Log to disk. Note that a file handle that error-ed is a no-op in these functions so no
// extra branching is needed to handle that.
va_list args_copy; va_list args_copy;
va_copy(args_copy, args); va_copy(args_copy, args);
DN_TicketMutex_Begin(&os->log_file_mutex); DN_TicketMutexBegin(&logger->file_mutex);
{ {
if (print_prefix) { if (print_prefix) {
DN_OS_FileWrite(&os->log_file, DN_Str8FromPtr(prefix_buffer, prefix_size.count), nullptr); DN_OS_FileWrite(&logger->file, DN_Str8FromPtr(prefix_buffer, prefix_size.count), nullptr);
DN_OS_FileWriteF(&os->log_file, nullptr, "%*s ", DN_Cast(int) prefix_size.padding, ""); DN_OS_FileWriteF(&logger->file, nullptr, "%*s ", DN_Cast(int) prefix_size.padding, "");
} }
DN_OS_FileWriteFV(&os->log_file, nullptr, fmt, args_copy); DN_OS_FileWriteFV(&logger->file, nullptr, fmt, args_copy);
if (!DN_BitIsSet(flags, DN_LogFlags_NoNewLine)) if (!DN_BitIsSet(flags, DN_LogFlags_NoNewLine))
DN_OS_FileWrite(&os->log_file, DN_Str8Lit("\n"), nullptr); DN_OS_FileWrite(&logger->file, DN_Str8Lit("\n"), nullptr);
} }
DN_TicketMutex_End(&os->log_file_mutex); DN_TicketMutexEnd(&logger->file_mutex);
va_end(args_copy); va_end(args_copy);
DN_TicketMutex_Begin(&os->log_mutex); DN_TicketMutexBegin(&logger->mutex);
{ if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_NoOutput)) {
if (print_prefix) if (print_prefix) {
if (DN_BitIsSet(logger->flags, DN_OSLoggerFlags_NoColour))
DN_OS_PrintF(DN_OSPrintDest_Err, "%.*s%*s ", DN_Cast(int) prefix_size.count, prefix_buffer, DN_Cast(int) prefix_size.padding, ""); DN_OS_PrintF(DN_OSPrintDest_Err, "%.*s%*s ", DN_Cast(int) prefix_size.count, prefix_buffer, DN_Cast(int) prefix_size.padding, "");
else
DN_OS_PrintF(DN_OSPrintDest_Err, "%.*s%*s ", DN_Cast(int) prefix_colour_size.count, prefix_colour_buffer, DN_Cast(int) prefix_colour_size.padding, "");
}
if (DN_BitIsSet(flags, DN_LogFlags_NoNewLine)) if (DN_BitIsSet(flags, DN_LogFlags_NoNewLine))
DN_OS_PrintFV(DN_OSPrintDest_Err, fmt, args); DN_OS_PrintFV(DN_OSPrintDest_Err, fmt, args);
else else
DN_OS_PrintLnFV(DN_OSPrintDest_Err, fmt, args); DN_OS_PrintLnFV(DN_OSPrintDest_Err, fmt, args);
} }
DN_TicketMutex_End(&os->log_mutex); DN_TicketMutexEnd(&logger->mutex);
}
DN_API void DN_OS_LoggerF(DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
DN_OS_LoggerFV(logger, type, call_site, flags, fmt, args);
va_end(args);
} }
DN_API void DN_OS_SetLogPrintFuncToOS() DN_API void DN_OS_SetLogPrintFuncToOS()
@@ -11537,7 +11656,6 @@ DN_API void DN_OS_SetLogPrintFuncToOS()
DN_LogSetPrintFunc(DN_OS_LogPrint, &dn->os); DN_LogSetPrintFunc(DN_OS_LogPrint, &dn->os);
} }
DN_API void *DN_OS_HeapBasicAlloc(DN_USize size) DN_API void *DN_OS_HeapBasicAlloc(DN_USize size)
{ {
void *result = DN_OS_MemAlloc(size, DN_ZMem_Yes); void *result = DN_OS_MemAlloc(size, DN_ZMem_Yes);
@@ -11714,6 +11832,7 @@ DN_API bool DN_OS_FileWrite(DN_OSFile *file, DN_Str8 buffer, DN_ErrSink *error)
return result; return result;
} }
typedef struct DN_OSFileWriteChunker_ DN_OSFileWriteChunker_;
struct DN_OSFileWriteChunker_ struct DN_OSFileWriteChunker_
{ {
DN_ErrSink *err; DN_ErrSink *err;
@@ -11975,45 +12094,7 @@ DN_API bool DN_OS_PathPop(DN_OSPath *fs_path)
return true; return true;
} }
DN_API DN_Str8 DN_OS_PathTo(DN_Arena *arena, DN_Str8 path, DN_Str8 path_separator) DN_API DN_Str8 DN_OS_PathBuildWithSeparatorAllocator(DN_Allocator allocator, DN_OSPath const *fs_path, DN_Str8 path_separator)
{
DN_OSPath fs_path = {};
DN_OS_PathAddRef(arena, &fs_path, path);
DN_Str8 result = DN_OS_PathBuildWithSeparator(arena, &fs_path, path_separator);
return result;
}
DN_API DN_Str8 DN_OS_PathToF(DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
va_list args;
va_start(args, fmt);
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
va_end(args);
DN_Str8 result = DN_OS_PathTo(arena, path, path_separator);
DN_TCScratchEnd(&scratch);
return result;
}
DN_API DN_Str8 DN_OS_Path(DN_Arena *arena, DN_Str8 path)
{
DN_Str8 result = DN_OS_PathTo(arena, path, DN_OSPathSeperatorString);
return result;
}
DN_API DN_Str8 DN_OS_PathF(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
va_list args;
va_start(args, fmt);
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
va_end(args);
DN_Str8 result = DN_OS_Path(arena, path);
DN_TCScratchEnd(&scratch);
return result;
}
DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs_path, DN_Str8 path_separator)
{ {
DN_Str8 result = {}; DN_Str8 result = {};
if (!fs_path || fs_path->links_size <= 0) if (!fs_path || fs_path->links_size <= 0)
@@ -12021,7 +12102,7 @@ DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs
// NOTE: Each link except the last one needs the path separator appended to it, '/' or '\\' // NOTE: Each link except the last one needs the path separator appended to it, '/' or '\\'
DN_USize string_size = (fs_path->has_prefix_path_separator ? path_separator.count : 0) + fs_path->string_size + ((fs_path->links_size - 1) * path_separator.count); DN_USize string_size = (fs_path->has_prefix_path_separator ? path_separator.count : 0) + fs_path->string_size + ((fs_path->links_size - 1) * path_separator.count);
result = DN_Str8AllocArena(string_size, DN_ZMem_No, arena); result = DN_Str8AllocAllocator(string_size, DN_ZMem_No, allocator);
if (result.data) { if (result.data) {
char *dest = result.data; char *dest = result.data;
if (fs_path->has_prefix_path_separator) { if (fs_path->has_prefix_path_separator) {
@@ -12045,7 +12126,88 @@ DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs
return result; return result;
} }
// NOTE: DN_OSExec DN_API DN_Str8 DN_OS_PathToArena(DN_Arena *arena, DN_Str8 path, DN_Str8 path_separator)
{
DN_OSPath fs_path = {};
DN_OS_PathAddRef(arena, &fs_path, path);
DN_Allocator allocator = DN_AllocatorFromArena(arena);
DN_Str8 result = DN_OS_PathBuildWithSeparatorAllocator(allocator, &fs_path, path_separator);
return result;
}
DN_API DN_Str8 DN_OS_PathToPool(DN_Pool *pool, DN_Str8 path, DN_Str8 path_separator)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(&pool->arena, 1);
DN_OSPath fs_path = {};
DN_OS_PathAddRef(&scratch.arena, &fs_path, path);
DN_Allocator allocator = DN_AllocatorFromPool(pool);
DN_Str8 result = DN_OS_PathBuildWithSeparatorAllocator(allocator, &fs_path, path_separator);
DN_TCScratchEnd(&scratch);
return result;
}
DN_API DN_Str8 DN_OS_PathToFmtArena(DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
va_list args;
va_start(args, fmt);
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
va_end(args);
DN_Str8 result = DN_OS_PathToArena(arena, path, path_separator);
DN_TCScratchEnd(&scratch);
return result;
}
DN_API DN_Str8 DN_OS_PathToFmtPool(DN_Pool *pool, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(&pool->arena, 1);
va_list args;
va_start(args, fmt);
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
va_end(args);
DN_Str8 result = DN_OS_PathToPool(pool, path, path_separator);
DN_TCScratchEnd(&scratch);
return result;
}
DN_API DN_Str8 DN_OS_PathArena(DN_Arena *arena, DN_Str8 path)
{
DN_Str8 result = DN_OS_PathToArena(arena, path, DN_OSPathSeparatorStr8);
return result;
}
DN_API DN_Str8 DN_OS_PathPool(DN_Pool *pool, DN_Str8 path)
{
DN_Str8 result = DN_OS_PathToPool(pool, path, DN_OSPathSeparatorStr8);
return result;
}
DN_API DN_Str8 DN_OS_PathFmtArena(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
va_list args;
va_start(args, fmt);
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
va_end(args);
DN_Str8 result = DN_OS_PathArena(arena, path);
DN_TCScratchEnd(&scratch);
return result;
}
DN_API DN_Str8 DN_OS_PathFmtPool(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(&pool->arena, 1);
va_list args;
va_start(args, fmt);
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
va_end(args);
DN_Str8 result = DN_OS_PathPool(pool, path);
DN_TCScratchEnd(&scratch);
return result;
}
DN_API DN_OSExecResult DN_OS_Exec(DN_Str8Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena, DN_ErrSink *error) DN_API DN_OSExecResult DN_OS_Exec(DN_Str8Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena, DN_ErrSink *error)
{ {
DN_OSExecAsyncHandle async_handle = DN_OS_ExecAsync(cmd_line, args, error); DN_OSExecAsyncHandle async_handle = DN_OS_ExecAsync(cmd_line, args, error);
@@ -12524,7 +12686,7 @@ DN_API DN_StackTrace DN_StackTraceFromAllocator(DN_Allocator allocator, DN_U16 l
return result; return result;
static DN_TicketMutex mutex = {}; static DN_TicketMutex mutex = {};
DN_TicketMutex_Begin(&mutex); DN_TicketMutexBegin(&mutex);
HANDLE thread = GetCurrentThread(); HANDLE thread = GetCurrentThread();
result.process = GetCurrentProcess(); result.process = GetCurrentProcess();
@@ -12570,7 +12732,7 @@ DN_API DN_StackTrace DN_StackTraceFromAllocator(DN_Allocator allocator, DN_U16 l
// If AddrPC.Offset == AddrReturn.Offset then we can detect recursion. // If AddrPC.Offset == AddrReturn.Offset then we can detect recursion.
DN_LArrayAppend(raw_frames, &raw_frames_count, frame.AddrPC.Offset); DN_LArrayAppend(raw_frames, &raw_frames_count, frame.AddrPC.Offset);
} }
DN_TicketMutex_End(&mutex); DN_TicketMutexEnd(&mutex);
result.base_addr = DN_Cast(DN_U64 *)DN_AllocatorAlloc(allocator, raw_frames_count * sizeof(DN_U64), alignof(DN_U64), DN_ZMem_No); result.base_addr = DN_Cast(DN_U64 *)DN_AllocatorAlloc(allocator, raw_frames_count * sizeof(DN_U64), alignof(DN_U64), DN_ZMem_No);
DN_Assert(result.base_addr); DN_Assert(result.base_addr);
@@ -14856,9 +15018,9 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
// add those characters in this branch, so overwrite the null // add those characters in this branch, so overwrite the null
// character, add the glob and re-null terminate the buffer. // character, add the glob and re-null terminate the buffer.
if (needs_asterisks) if (needs_asterisks)
adjusted_path = DN_OS_PathF(&scratch.arena, "%.*s*", DN_Str8PrintFmt(path)); adjusted_path = DN_OS_PathFmtArena(&scratch.arena, "%.*s*", DN_Str8PrintFmt(path));
else else
adjusted_path = DN_OS_PathF(&scratch.arena, "%.*s/*", DN_Str8PrintFmt(path)); adjusted_path = DN_OS_PathFmtArena(&scratch.arena, "%.*s/*", DN_Str8PrintFmt(path));
} }
path16 = DN_OS_W32Str8ToStr16(&scratch.arena, adjusted_path); path16 = DN_OS_W32Str8ToStr16(&scratch.arena, adjusted_path);
@@ -16037,6 +16199,7 @@ void DN_NET_EndFinishedRequest(DN_NETRequest *request)
#endif // #if DN_WITH_NET #endif // #if DN_WITH_NET
#if DN_WITH_NET_CURL #if DN_WITH_NET_CURL
typedef struct DN_NETCurlRequest DN_NETCurlRequest;
struct DN_NETCurlRequest struct DN_NETCurlRequest
{ {
void *handle; void *handle;
@@ -16055,6 +16218,7 @@ enum DN_NETCurlRingEventType
DN_NETCurlRingEventType_DeinitRequest, DN_NETCurlRingEventType_DeinitRequest,
}; };
typedef struct DN_NETCurlRingEvent_ DN_NETCurlRingEvent_;
struct DN_NETCurlRingEvent_ struct DN_NETCurlRingEvent_
{ {
DN_NETCurlRingEventType type; DN_NETCurlRingEventType type;
@@ -16756,6 +16920,7 @@ DN_NETResponse DN_NET_CurlWaitForAnyResponse(DN_NETCore *net, DN_Arena *arena, D
#include <emscripten/fetch.h> #include <emscripten/fetch.h>
#include <emscripten/websocket.h> #include <emscripten/websocket.h>
typedef struct DN_NETEmcWSEvent DN_NETEmcWSEvent;
struct DN_NETEmcWSEvent struct DN_NETEmcWSEvent
{ {
DN_NETResponseState state; DN_NETResponseState state;
@@ -16763,6 +16928,7 @@ struct DN_NETEmcWSEvent
DN_NETEmcWSEvent *next; DN_NETEmcWSEvent *next;
}; };
typedef struct DN_NETEmcCore DN_NETEmcCore;
struct DN_NETEmcCore struct DN_NETEmcCore
{ {
DN_Pool pool; DN_Pool pool;
@@ -16770,6 +16936,7 @@ struct DN_NETEmcCore
DN_NETRequest *free_list; // Request pool that new requests will use before allocating DN_NETRequest *free_list; // Request pool that new requests will use before allocating
}; };
typedef struct DN_NETEmcRequest DN_NETEmcRequest;
struct DN_NETEmcRequest struct DN_NETEmcRequest
{ {
int socket; int socket;
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -649,9 +649,9 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
// add those characters in this branch, so overwrite the null // add those characters in this branch, so overwrite the null
// character, add the glob and re-null terminate the buffer. // character, add the glob and re-null terminate the buffer.
if (needs_asterisks) if (needs_asterisks)
adjusted_path = DN_OS_PathF(&scratch.arena, "%.*s*", DN_Str8PrintFmt(path)); adjusted_path = DN_OS_PathFmtArena(&scratch.arena, "%.*s*", DN_Str8PrintFmt(path));
else else
adjusted_path = DN_OS_PathF(&scratch.arena, "%.*s/*", DN_Str8PrintFmt(path)); adjusted_path = DN_OS_PathFmtArena(&scratch.arena, "%.*s/*", DN_Str8PrintFmt(path));
} }
path16 = DN_OS_W32Str8ToStr16(&scratch.arena, adjusted_path); path16 = DN_OS_W32Str8ToStr16(&scratch.arena, adjusted_path);
+278 -111
View File
@@ -546,24 +546,24 @@ DN_API DN_CPUReport DN_CPUGetReport()
return result; return result;
} }
DN_API void DN_TicketMutex_Begin(DN_TicketMutex *mutex) DN_API void DN_TicketMutexBegin(DN_TicketMutex *mutex)
{ {
DN_UInt ticket = DN_AtomicAddU32(&mutex->ticket, 1); DN_UInt ticket = DN_AtomicAddU32(&mutex->ticket, 1);
DN_TicketMutex_BeginTicket(mutex, ticket); DN_TicketMutexBeginTicket(mutex, ticket);
} }
DN_API void DN_TicketMutex_End(DN_TicketMutex *mutex) DN_API void DN_TicketMutexEnd(DN_TicketMutex *mutex)
{ {
DN_AtomicAddU32(&mutex->serving, 1); DN_AtomicAddU32(&mutex->serving, 1);
} }
DN_API DN_UInt DN_TicketMutex_MakeTicket(DN_TicketMutex *mutex) DN_API DN_UInt DN_TicketMutexMakeTicket(DN_TicketMutex *mutex)
{ {
DN_UInt result = DN_AtomicAddU32(&mutex->ticket, 1); DN_UInt result = DN_AtomicAddU32(&mutex->ticket, 1);
return result; return result;
} }
DN_API void DN_TicketMutex_BeginTicket(DN_TicketMutex const *mutex, DN_UInt ticket) DN_API void DN_TicketMutexBeginTicket(DN_TicketMutex const *mutex, DN_UInt ticket)
{ {
DN_AssertF(mutex->serving <= ticket, DN_AssertF(mutex->serving <= ticket,
"Mutex skipped ticket? Was ticket generated by the correct mutex via MakeTicket? ticket = %u, " "Mutex skipped ticket? Was ticket generated by the correct mutex via MakeTicket? ticket = %u, "
@@ -576,7 +576,7 @@ DN_API void DN_TicketMutex_BeginTicket(DN_TicketMutex const *mutex, DN_UInt tick
} }
} }
DN_API bool DN_TicketMutex_CanLock(DN_TicketMutex const *mutex, DN_UInt ticket) DN_API bool DN_TicketMutexCanLock(DN_TicketMutex const *mutex, DN_UInt ticket)
{ {
bool result = (ticket == mutex->serving); bool result = (ticket == mutex->serving);
return result; return result;
@@ -1766,6 +1766,12 @@ DN_API void DN_ArenaDeinit(DN_Arena *arena)
DN_MemListDeinit(arena->mem); DN_MemListDeinit(arena->mem);
} }
DN_API bool DN_ArenaOwnsPtr(DN_Arena const *arena, void *ptr)
{
bool result = DN_MemListOwnsPtr(arena->mem, ptr);
return result;
}
DN_API DN_Pool DN_PoolFromArena(DN_Arena *arena, DN_U8 align) DN_API DN_Pool DN_PoolFromArena(DN_Arena *arena, DN_U8 align)
{ {
DN_Pool result = {}; DN_Pool result = {};
@@ -5056,7 +5062,6 @@ DN_API DN_U8x16 DN_U8x16FromPtrHex32(char const *hex, DN_USize hex_count)
{ {
DN_U8x16 result = {}; DN_U8x16 result = {};
DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count)); DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count));
DN_Assert(hex_trimmed.count / 2 == sizeof result.data);
DN_USize bytes_written = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, sizeof result.data); DN_USize bytes_written = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, sizeof result.data);
DN_Assert(bytes_written == sizeof result.data); DN_Assert(bytes_written == sizeof result.data);
return result; return result;
@@ -5066,7 +5071,6 @@ DN_API DN_U8x32 DN_U8x32FromPtrHex64(char const *hex, DN_USize hex_count)
{ {
DN_U8x32 result = {}; DN_U8x32 result = {};
DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count)); DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count));
DN_Assert(hex_trimmed.count / 2 == sizeof result.data);
DN_USize bytes_written = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, sizeof result.data); DN_USize bytes_written = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, sizeof result.data);
DN_Assert(bytes_written == sizeof result.data); DN_Assert(bytes_written == sizeof result.data);
return result; return result;
@@ -8092,6 +8096,7 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a,
return result; return result;
} }
typedef struct DN_ArrayFindEqMemcmpContext_ DN_ArrayFindEqMemcmpContext_;
struct DN_ArrayFindEqMemcmpContext_ struct DN_ArrayFindEqMemcmpContext_
{ {
DN_USize elem_size; DN_USize elem_size;
@@ -9627,6 +9632,7 @@ DN_API void DN_TestVerifyBytesF(DN_TestCore *test, DN_CallSite call_site, DN_Str
#if defined(DN_PLATFORM_WIN32) && defined(DN_COMPILER_MSVC) #if defined(DN_PLATFORM_WIN32) && defined(DN_COMPILER_MSVC)
// NOTE: Taken from MSDN __cpuid example implementation // NOTE: Taken from MSDN __cpuid example implementation
// https://learn.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-170 // https://learn.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-170
typedef struct DN_RefImplCPUReport DN_RefImplCPUReport;
struct DN_RefImplCPUReport { struct DN_RefImplCPUReport {
unsigned int nIds_ = 0; unsigned int nIds_ = 0;
unsigned int nExIds_ = 0; unsigned int nExIds_ = 0;
@@ -9789,22 +9795,22 @@ DN_API DN_TestCore DN_TestSuite(DN_Arena *arena_)
{ {
for (DN_TestScopeF(&result, "[TicketMutex] Start and stop")) { for (DN_TestScopeF(&result, "[TicketMutex] Start and stop")) {
DN_TicketMutex mutex = {}; DN_TicketMutex mutex = {};
DN_TicketMutex_Begin(&mutex); DN_TicketMutexBegin(&mutex);
DN_TicketMutex_End(&mutex); DN_TicketMutexEnd(&mutex);
DN_TestVerifyUSizeEq(&result, mutex.ticket, mutex.serving); DN_TestVerifyUSizeEq(&result, mutex.ticket, mutex.serving);
} }
for (DN_TestScopeF(&result, "[TicketMutex] Start and stop w/ advanced API")) { for (DN_TestScopeF(&result, "[TicketMutex] Start and stop w/ advanced API")) {
DN_TicketMutex mutex = {}; DN_TicketMutex mutex = {};
unsigned int ticket_a = DN_TicketMutex_MakeTicket(&mutex); DN_UInt ticket_a = DN_TicketMutexMakeTicket(&mutex);
unsigned int ticket_b = DN_TicketMutex_MakeTicket(&mutex); DN_UInt ticket_b = DN_TicketMutexMakeTicket(&mutex);
DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutex_CanLock(&mutex, ticket_b) == false); DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutexCanLock(&mutex, ticket_b) == false);
DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutex_CanLock(&mutex, ticket_a) == true); DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutexCanLock(&mutex, ticket_a) == true);
DN_TicketMutex_BeginTicket(&mutex, ticket_a); DN_TicketMutexBeginTicket(&mutex, ticket_a);
DN_TicketMutex_End(&mutex); DN_TicketMutexEnd(&mutex);
DN_TicketMutex_BeginTicket(&mutex, ticket_b); DN_TicketMutexBeginTicket(&mutex, ticket_b);
DN_TicketMutex_End(&mutex); DN_TicketMutexEnd(&mutex);
DN_TestVerifyUSizeEq(&result, mutex.ticket, mutex.serving); DN_TestVerifyUSizeEq(&result, mutex.ticket, mutex.serving);
DN_TestVerifyUSizeEq(&result, mutex.ticket, ticket_b + 1); DN_TestVerifyUSizeEq(&result, mutex.ticket, ticket_b + 1);
@@ -11287,7 +11293,7 @@ DN_API void DN_LeakTrackAlloc_(DN_LeakTracker *leak, void *ptr, DN_USize size, b
if (!ptr) if (!ptr)
return; return;
DN_TicketMutex_Begin(&leak->alloc_table_mutex); DN_TicketMutexBegin(&leak->alloc_table_mutex);
DN_Str8 stack_trace = DN_Str8FromStackTraceNowHeap(128, 3 /*skip*/); DN_Str8 stack_trace = DN_Str8FromStackTraceNowHeap(128, 3 /*skip*/);
DN_HTable* alloc_table = &leak->alloc_table; DN_HTable* alloc_table = &leak->alloc_table;
@@ -11333,7 +11339,7 @@ DN_API void DN_LeakTrackAlloc_(DN_LeakTracker *leak, void *ptr, DN_USize size, b
alloc->stack_trace = stack_trace; alloc->stack_trace = stack_trace;
alloc->flags |= leak_permitted ? DN_LeakAllocFlag_LeakPermitted : 0; alloc->flags |= leak_permitted ? DN_LeakAllocFlag_LeakPermitted : 0;
leak->alloc_table_bytes_allocated_for_stack_traces += alloc->stack_trace.count; leak->alloc_table_bytes_allocated_for_stack_traces += alloc->stack_trace.count;
DN_TicketMutex_End(&leak->alloc_table_mutex); DN_TicketMutexEnd(&leak->alloc_table_mutex);
} }
DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr) DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
@@ -11341,7 +11347,7 @@ DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
if (!ptr) if (!ptr)
return; return;
DN_TicketMutex_Begin(&leak->alloc_table_mutex); DN_TicketMutexBegin(&leak->alloc_table_mutex);
DN_Str8 stack_trace = DN_Str8FromStackTraceNowHeap(128, 3 /*skip*/); DN_Str8 stack_trace = DN_Str8FromStackTraceNowHeap(128, 3 /*skip*/);
DN_HTable* alloc_table = &leak->alloc_table; DN_HTable* alloc_table = &leak->alloc_table;
@@ -11382,7 +11388,7 @@ DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
alloc->flags |= DN_LeakAllocFlag_Freed; alloc->flags |= DN_LeakAllocFlag_Freed;
alloc->freed_stack_trace = stack_trace; alloc->freed_stack_trace = stack_trace;
leak->alloc_table_bytes_allocated_for_stack_traces += alloc->freed_stack_trace.count; leak->alloc_table_bytes_allocated_for_stack_traces += alloc->freed_stack_trace.count;
DN_TicketMutex_End(&leak->alloc_table_mutex); DN_TicketMutexEnd(&leak->alloc_table_mutex);
} }
DN_API void DN_LeakDump_(DN_LeakTracker *leak) DN_API void DN_LeakDump_(DN_LeakTracker *leak)
@@ -11444,52 +11450,150 @@ DN_API DN_Str8 DN_OS_Str8FromStr8BuilderHeap(DN_Str8Builder const *builder)
DN_API void DN_OS_LogPrint(DN_LogTypeParam type, void *user_data, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, va_list args) DN_API void DN_OS_LogPrint(DN_LogTypeParam type, void *user_data, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, va_list args)
{ {
DN_Assert(user_data);
DN_OSCore *os = DN_Cast(DN_OSCore *)user_data; DN_OSCore *os = DN_Cast(DN_OSCore *)user_data;
DN_OSLogger *logger = &os->logger;
DN_OS_LoggerFV(logger, type, call_site, flags, fmt, args);
}
// NOTE: Open log file for appending if requested DN_API DN_Str8 DN_OS_LoggerGetRotateFilePath(DN_Str8 base_file_path, DN_Arena *arena, DN_USize rotate_index)
DN_TicketMutex_Begin(&os->log_file_mutex); {
if (os->log_to_file && !os->log_file.handle && !os->log_file.error) { DN_Str8 result = {};
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0); if (rotate_index == 0)
DN_Str8 exe_dir = DN_OS_EXEDir(&scratch.arena); result = DN_OS_PathFmtArena(arena, "%.*s", DN_Str8PrintFmt(base_file_path));
DN_Str8 log_path = DN_OS_PathF(&scratch.arena, "%.*s/dn.log", DN_Str8PrintFmt(exe_dir)); else
os->log_file = DN_OS_FileOpen(log_path, DN_OSFileOpen_CreateAlways, DN_OSFileAccess_AppendOnly, nullptr); result = DN_OS_PathFmtArena(arena, "%.*s.%zu", DN_Str8PrintFmt(base_file_path), rotate_index);
DN_TCScratchEnd(&scratch); return result;
}
static void DN_OS_LoggerSetFilePathNoMutex_(DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path)
{
if (logger->file_path.data) {
DN_AssertF(DN_MemListOwnsPtr(pool->arena->mem, logger->file_path.data),
"If there's a pre-existing file path set in the logger, it must be deallocated by "
" the caller and cleared. If it has been previously allocated with the exact same "
" pool was allocated with the same pool then we will deallocate it for you.");
DN_PoolDealloc(pool, logger->file_path.data);
logger->file_path = {};
} }
DN_TicketMutex_End(&os->log_file_mutex); DN_OS_FileClose(&logger->file);
logger->file_path = DN_OS_PathFmtPool(pool, "%.*s", DN_Str8PrintFmt(file_path));
// NOTE: Clear the sticky file error flag if it was set
logger->flags &= ~DN_OSLoggerFlags_FileError;
}
DN_API void DN_OS_LoggerSetFilePath(DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path)
{
DN_TicketMutexBegin(&logger->file_mutex);
DN_OS_LoggerSetFilePathNoMutex_(logger, pool, file_path);
DN_TicketMutexEnd(&logger->file_mutex);
}
static void DN_OS_DoLogFileSetupAndRotation_(DN_OSLogger *logger)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
DN_Str8 error = {};
DN_TicketMutexBegin(&logger->file_mutex);
if (logger->flags & DN_OSLoggerFlags_File) {
// NOTE: Set a default file path to log to if it's not been set yet
if (logger->file_path.count == 0) {
DN_Str8 exe_dir = DN_OS_EXEDir(&scratch.arena);
DN_Str8 default_file_path = DN_OS_PathFmtArena(&scratch.arena, "%.*s/dn.log", DN_Str8PrintFmt(exe_dir));
DN_OS_LoggerSetFilePathNoMutex_(logger, DN_TCMainPool(), default_file_path);
}
// NOTE Rotate the log file if the criteria is met
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError) && logger->rotate_every_n_bytes && logger->rotate_count) {
DN_Assert(logger->file_path.count);
DN_Assert(logger->rotate_every_n_bytes > 0);
DN_OSPathInfo file_info = DN_OS_PathInfo(logger->file_path);
bool needs_rotate = file_info.size >= logger->rotate_every_n_bytes;
if (needs_rotate) {
DN_OS_FileClose(&logger->file);
// NOTE: Loop through all the rotated log files from [rotate_count-1..1]. The rotated log
// file at `rotate_count-1` gets deleted and `rotate_count-2` gets moved into
// `rotate_count-1` and so forth
for (DN_USize offset = 0; offset < (logger->rotate_count - 1); offset++) {
DN_USize const file_index = logger->rotate_count - (offset + 1);
DN_Str8 file_path = DN_OS_LoggerGetRotateFilePath(logger->file_path, &scratch.arena, file_index);
DN_Str8 prev_file_path = DN_OS_LoggerGetRotateFilePath(logger->file_path, &scratch.arena, file_index - 1);
DN_OS_FileMove(prev_file_path, file_path, true, nullptr);
}
}
// NOTE: After rotating, check the file size of the log file we will write to again. If the
// file size is still greater than the rotate size, then there was an error when we
// attempted to rotate the logs. Set the sticky file flag error to disable to logger and
// inform the user.
if (needs_rotate) {
DN_OSPathInfo recheck_file_info = DN_OS_PathInfo(logger->file_path);
if (recheck_file_info.size >= logger->rotate_every_n_bytes) {
logger->flags |= DN_OSLoggerFlags_FileError;
error = DN_Str8FromFmtArena(&scratch.arena, "Rotating of log files failed at (%.*s). Logging to disk is disabled", DN_Str8PrintFmt(logger->file_path));
}
}
}
// NOTE: Open the file requested by the logger if it hasn't been opened yet
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError)) {
if (!logger->file.handle && !logger->file.error) {
DN_OSPathInfo file_path_info = DN_OS_PathInfo(logger->file_path);
if (file_path_info.exists && file_path_info.type != DN_OSPathInfoType_File) {
logger->flags |= DN_OSLoggerFlags_FileError;
error = DN_Str8FromFmtArena(&scratch.arena, "File path to log to (%.*s) exists but is not a writable file. Logging to disk is disabled.", DN_Str8PrintFmt(logger->file_path));
}
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError))
logger->file = DN_OS_FileOpen(logger->file_path, DN_OSFileOpen_OpenAlways, DN_OSFileAccess_AppendOnly, nullptr);
}
}
// NOTE: Set the sticky error flag on the file if opening failed. The sticky flag ensures we
// only notify the user once of a file open failure per unique base file path
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError)) {
if (logger->file.error) {
logger->flags |= DN_OSLoggerFlags_FileError;
error = DN_Str8FromFmtArena(&scratch.arena, "Failed to open file (%.*s) for logging. Logging to disk is disabled", DN_Str8PrintFmt(logger->file_path));
}
}
}
DN_TicketMutexEnd(&logger->file_mutex);
// NOTE: Error is logged outside of the mutex since logging will recurse back into the OS logger
if (error.count)
DN_LogWarningF("%.*s", DN_Str8PrintFmt(error));
DN_TCScratchEnd(&scratch);
}
DN_API void DN_OS_LoggerFV(DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, va_list args)
{
DN_OS_DoLogFileSetupAndRotation_(logger);
bool print_prefix = DN_BitIsNotSet(flags, DN_LogFlags_NoPrefix); bool print_prefix = DN_BitIsNotSet(flags, DN_LogFlags_NoPrefix);
char prefix_buffer[128] = {}; char prefix_buffer[128] = {};
DN_LogPrefixSize prefix_size = {}; DN_LogPrefixSize prefix_size = {};
char prefix_colour_buffer[128] = {};
DN_LogPrefixSize prefix_colour_size = {};
if (print_prefix) { if (print_prefix) {
DN_LogStyle style = {}; // NOTE: Generate 2 variants of the style (colour and colour-less) for printing the prefix of
if (!os->log_no_colour) { // the log line
style.colour = true; DN_LogStyle style_colour = {};
style.bold = DN_LogBold_Yes; style_colour.bold = DN_LogBold_Yes;
style_colour.colour = true;
if (type.is_u32_enum) { if (type.is_u32_enum) {
switch (type.u32) { switch (type.u32) {
case DN_LogType_Debug: { case DN_LogType_Debug: style_colour.colour = false; style_colour.bold = DN_LogBold_No; break;
case DN_LogType_Info: style_colour.g = 0x87; style_colour.b = 0xff; break;
case DN_LogType_Warning: style_colour.r = 0xff; style_colour.g = 0xff; break;
case DN_LogType_Error: style_colour.r = 0xff; break;
}
}
DN_LogStyle style = style_colour;
style.colour = false; style.colour = false;
style.bold = DN_LogBold_No;
} break;
case DN_LogType_Info: {
style.g = 0x87;
style.b = 0xff;
} break;
case DN_LogType_Warning: {
style.r = 0xff;
style.g = 0xff;
} break;
case DN_LogType_Error: {
style.r = 0xff;
} break;
}
}
}
// NOTE: Build the log prefix
DN_Date os_date = DN_OS_DateLocalTimeNow(); DN_Date os_date = DN_OS_DateLocalTimeNow();
DN_LogDate log_date = {}; DN_LogDate log_date = {};
log_date.year = os_date.year; log_date.year = os_date.year;
@@ -11498,35 +11602,50 @@ DN_API void DN_OS_LogPrint(DN_LogTypeParam type, void *user_data, DN_CallSite ca
log_date.hour = os_date.hour; log_date.hour = os_date.hour;
log_date.minute = os_date.minutes; log_date.minute = os_date.minutes;
log_date.second = os_date.seconds; log_date.second = os_date.seconds;
prefix_size = DN_LogMakePrefix(style, type, call_site, log_date, prefix_buffer, sizeof(prefix_buffer)); prefix_size = DN_LogMakePrefix(style, type, call_site, log_date, prefix_buffer, DN_ArrayCountU(prefix_buffer));
prefix_colour_size = DN_LogMakePrefix(style_colour, type, call_site, log_date, prefix_colour_buffer, DN_ArrayCountU(prefix_colour_buffer));
} }
// NOTE: Log to disk. Note that a file handle that error-ed is a no-op in these functions so no
// extra branching is needed to handle that.
va_list args_copy; va_list args_copy;
va_copy(args_copy, args); va_copy(args_copy, args);
DN_TicketMutex_Begin(&os->log_file_mutex); DN_TicketMutexBegin(&logger->file_mutex);
{ {
if (print_prefix) { if (print_prefix) {
DN_OS_FileWrite(&os->log_file, DN_Str8FromPtr(prefix_buffer, prefix_size.count), nullptr); DN_OS_FileWrite(&logger->file, DN_Str8FromPtr(prefix_buffer, prefix_size.count), nullptr);
DN_OS_FileWriteF(&os->log_file, nullptr, "%*s ", DN_Cast(int) prefix_size.padding, ""); DN_OS_FileWriteF(&logger->file, nullptr, "%*s ", DN_Cast(int) prefix_size.padding, "");
} }
DN_OS_FileWriteFV(&os->log_file, nullptr, fmt, args_copy); DN_OS_FileWriteFV(&logger->file, nullptr, fmt, args_copy);
if (!DN_BitIsSet(flags, DN_LogFlags_NoNewLine)) if (!DN_BitIsSet(flags, DN_LogFlags_NoNewLine))
DN_OS_FileWrite(&os->log_file, DN_Str8Lit("\n"), nullptr); DN_OS_FileWrite(&logger->file, DN_Str8Lit("\n"), nullptr);
} }
DN_TicketMutex_End(&os->log_file_mutex); DN_TicketMutexEnd(&logger->file_mutex);
va_end(args_copy); va_end(args_copy);
DN_TicketMutex_Begin(&os->log_mutex); DN_TicketMutexBegin(&logger->mutex);
{ if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_NoOutput)) {
if (print_prefix) if (print_prefix) {
if (DN_BitIsSet(logger->flags, DN_OSLoggerFlags_NoColour))
DN_OS_PrintF(DN_OSPrintDest_Err, "%.*s%*s ", DN_Cast(int) prefix_size.count, prefix_buffer, DN_Cast(int) prefix_size.padding, ""); DN_OS_PrintF(DN_OSPrintDest_Err, "%.*s%*s ", DN_Cast(int) prefix_size.count, prefix_buffer, DN_Cast(int) prefix_size.padding, "");
else
DN_OS_PrintF(DN_OSPrintDest_Err, "%.*s%*s ", DN_Cast(int) prefix_colour_size.count, prefix_colour_buffer, DN_Cast(int) prefix_colour_size.padding, "");
}
if (DN_BitIsSet(flags, DN_LogFlags_NoNewLine)) if (DN_BitIsSet(flags, DN_LogFlags_NoNewLine))
DN_OS_PrintFV(DN_OSPrintDest_Err, fmt, args); DN_OS_PrintFV(DN_OSPrintDest_Err, fmt, args);
else else
DN_OS_PrintLnFV(DN_OSPrintDest_Err, fmt, args); DN_OS_PrintLnFV(DN_OSPrintDest_Err, fmt, args);
} }
DN_TicketMutex_End(&os->log_mutex); DN_TicketMutexEnd(&logger->mutex);
}
DN_API void DN_OS_LoggerF(DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
DN_OS_LoggerFV(logger, type, call_site, flags, fmt, args);
va_end(args);
} }
DN_API void DN_OS_SetLogPrintFuncToOS() DN_API void DN_OS_SetLogPrintFuncToOS()
@@ -11535,7 +11654,6 @@ DN_API void DN_OS_SetLogPrintFuncToOS()
DN_LogSetPrintFunc(DN_OS_LogPrint, &dn->os); DN_LogSetPrintFunc(DN_OS_LogPrint, &dn->os);
} }
DN_API void *DN_OS_HeapBasicAlloc(DN_USize size) DN_API void *DN_OS_HeapBasicAlloc(DN_USize size)
{ {
void *result = DN_OS_MemAlloc(size, DN_ZMem_Yes); void *result = DN_OS_MemAlloc(size, DN_ZMem_Yes);
@@ -11712,6 +11830,7 @@ DN_API bool DN_OS_FileWrite(DN_OSFile *file, DN_Str8 buffer, DN_ErrSink *error)
return result; return result;
} }
typedef struct DN_OSFileWriteChunker_ DN_OSFileWriteChunker_;
struct DN_OSFileWriteChunker_ struct DN_OSFileWriteChunker_
{ {
DN_ErrSink *err; DN_ErrSink *err;
@@ -11973,45 +12092,7 @@ DN_API bool DN_OS_PathPop(DN_OSPath *fs_path)
return true; return true;
} }
DN_API DN_Str8 DN_OS_PathTo(DN_Arena *arena, DN_Str8 path, DN_Str8 path_separator) DN_API DN_Str8 DN_OS_PathBuildWithSeparatorAllocator(DN_Allocator allocator, DN_OSPath const *fs_path, DN_Str8 path_separator)
{
DN_OSPath fs_path = {};
DN_OS_PathAddRef(arena, &fs_path, path);
DN_Str8 result = DN_OS_PathBuildWithSeparator(arena, &fs_path, path_separator);
return result;
}
DN_API DN_Str8 DN_OS_PathToF(DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
va_list args;
va_start(args, fmt);
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
va_end(args);
DN_Str8 result = DN_OS_PathTo(arena, path, path_separator);
DN_TCScratchEnd(&scratch);
return result;
}
DN_API DN_Str8 DN_OS_Path(DN_Arena *arena, DN_Str8 path)
{
DN_Str8 result = DN_OS_PathTo(arena, path, DN_OSPathSeperatorString);
return result;
}
DN_API DN_Str8 DN_OS_PathF(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
va_list args;
va_start(args, fmt);
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
va_end(args);
DN_Str8 result = DN_OS_Path(arena, path);
DN_TCScratchEnd(&scratch);
return result;
}
DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs_path, DN_Str8 path_separator)
{ {
DN_Str8 result = {}; DN_Str8 result = {};
if (!fs_path || fs_path->links_size <= 0) if (!fs_path || fs_path->links_size <= 0)
@@ -12019,7 +12100,7 @@ DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs
// NOTE: Each link except the last one needs the path separator appended to it, '/' or '\\' // NOTE: Each link except the last one needs the path separator appended to it, '/' or '\\'
DN_USize string_size = (fs_path->has_prefix_path_separator ? path_separator.count : 0) + fs_path->string_size + ((fs_path->links_size - 1) * path_separator.count); DN_USize string_size = (fs_path->has_prefix_path_separator ? path_separator.count : 0) + fs_path->string_size + ((fs_path->links_size - 1) * path_separator.count);
result = DN_Str8AllocArena(string_size, DN_ZMem_No, arena); result = DN_Str8AllocAllocator(string_size, DN_ZMem_No, allocator);
if (result.data) { if (result.data) {
char *dest = result.data; char *dest = result.data;
if (fs_path->has_prefix_path_separator) { if (fs_path->has_prefix_path_separator) {
@@ -12043,7 +12124,88 @@ DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs
return result; return result;
} }
// NOTE: DN_OSExec DN_API DN_Str8 DN_OS_PathToArena(DN_Arena *arena, DN_Str8 path, DN_Str8 path_separator)
{
DN_OSPath fs_path = {};
DN_OS_PathAddRef(arena, &fs_path, path);
DN_Allocator allocator = DN_AllocatorFromArena(arena);
DN_Str8 result = DN_OS_PathBuildWithSeparatorAllocator(allocator, &fs_path, path_separator);
return result;
}
DN_API DN_Str8 DN_OS_PathToPool(DN_Pool *pool, DN_Str8 path, DN_Str8 path_separator)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(&pool->arena, 1);
DN_OSPath fs_path = {};
DN_OS_PathAddRef(&scratch.arena, &fs_path, path);
DN_Allocator allocator = DN_AllocatorFromPool(pool);
DN_Str8 result = DN_OS_PathBuildWithSeparatorAllocator(allocator, &fs_path, path_separator);
DN_TCScratchEnd(&scratch);
return result;
}
DN_API DN_Str8 DN_OS_PathToFmtArena(DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
va_list args;
va_start(args, fmt);
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
va_end(args);
DN_Str8 result = DN_OS_PathToArena(arena, path, path_separator);
DN_TCScratchEnd(&scratch);
return result;
}
DN_API DN_Str8 DN_OS_PathToFmtPool(DN_Pool *pool, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(&pool->arena, 1);
va_list args;
va_start(args, fmt);
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
va_end(args);
DN_Str8 result = DN_OS_PathToPool(pool, path, path_separator);
DN_TCScratchEnd(&scratch);
return result;
}
DN_API DN_Str8 DN_OS_PathArena(DN_Arena *arena, DN_Str8 path)
{
DN_Str8 result = DN_OS_PathToArena(arena, path, DN_OSPathSeparatorStr8);
return result;
}
DN_API DN_Str8 DN_OS_PathPool(DN_Pool *pool, DN_Str8 path)
{
DN_Str8 result = DN_OS_PathToPool(pool, path, DN_OSPathSeparatorStr8);
return result;
}
DN_API DN_Str8 DN_OS_PathFmtArena(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
va_list args;
va_start(args, fmt);
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
va_end(args);
DN_Str8 result = DN_OS_PathArena(arena, path);
DN_TCScratchEnd(&scratch);
return result;
}
DN_API DN_Str8 DN_OS_PathFmtPool(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...)
{
DN_TCScratch scratch = DN_TCScratchBeginArena(&pool->arena, 1);
va_list args;
va_start(args, fmt);
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
va_end(args);
DN_Str8 result = DN_OS_PathPool(pool, path);
DN_TCScratchEnd(&scratch);
return result;
}
DN_API DN_OSExecResult DN_OS_Exec(DN_Str8Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena, DN_ErrSink *error) DN_API DN_OSExecResult DN_OS_Exec(DN_Str8Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena, DN_ErrSink *error)
{ {
DN_OSExecAsyncHandle async_handle = DN_OS_ExecAsync(cmd_line, args, error); DN_OSExecAsyncHandle async_handle = DN_OS_ExecAsync(cmd_line, args, error);
@@ -12522,7 +12684,7 @@ DN_API DN_StackTrace DN_StackTraceFromAllocator(DN_Allocator allocator, DN_U16 l
return result; return result;
static DN_TicketMutex mutex = {}; static DN_TicketMutex mutex = {};
DN_TicketMutex_Begin(&mutex); DN_TicketMutexBegin(&mutex);
HANDLE thread = GetCurrentThread(); HANDLE thread = GetCurrentThread();
result.process = GetCurrentProcess(); result.process = GetCurrentProcess();
@@ -12568,7 +12730,7 @@ DN_API DN_StackTrace DN_StackTraceFromAllocator(DN_Allocator allocator, DN_U16 l
// If AddrPC.Offset == AddrReturn.Offset then we can detect recursion. // If AddrPC.Offset == AddrReturn.Offset then we can detect recursion.
DN_LArrayAppend(raw_frames, &raw_frames_count, frame.AddrPC.Offset); DN_LArrayAppend(raw_frames, &raw_frames_count, frame.AddrPC.Offset);
} }
DN_TicketMutex_End(&mutex); DN_TicketMutexEnd(&mutex);
result.base_addr = DN_Cast(DN_U64 *)DN_AllocatorAlloc(allocator, raw_frames_count * sizeof(DN_U64), alignof(DN_U64), DN_ZMem_No); result.base_addr = DN_Cast(DN_U64 *)DN_AllocatorAlloc(allocator, raw_frames_count * sizeof(DN_U64), alignof(DN_U64), DN_ZMem_No);
DN_Assert(result.base_addr); DN_Assert(result.base_addr);
@@ -12901,6 +13063,7 @@ void DN_NET_EndFinishedRequest(DN_NETRequest *request)
#endif // #if DN_WITH_NET #endif // #if DN_WITH_NET
#if DN_WITH_NET_CURL #if DN_WITH_NET_CURL
typedef struct DN_NETCurlRequest DN_NETCurlRequest;
struct DN_NETCurlRequest struct DN_NETCurlRequest
{ {
void *handle; void *handle;
@@ -12919,6 +13082,7 @@ enum DN_NETCurlRingEventType
DN_NETCurlRingEventType_DeinitRequest, DN_NETCurlRingEventType_DeinitRequest,
}; };
typedef struct DN_NETCurlRingEvent_ DN_NETCurlRingEvent_;
struct DN_NETCurlRingEvent_ struct DN_NETCurlRingEvent_
{ {
DN_NETCurlRingEventType type; DN_NETCurlRingEventType type;
@@ -13620,6 +13784,7 @@ DN_NETResponse DN_NET_CurlWaitForAnyResponse(DN_NETCore *net, DN_Arena *arena, D
#include <emscripten/fetch.h> #include <emscripten/fetch.h>
#include <emscripten/websocket.h> #include <emscripten/websocket.h>
typedef struct DN_NETEmcWSEvent DN_NETEmcWSEvent;
struct DN_NETEmcWSEvent struct DN_NETEmcWSEvent
{ {
DN_NETResponseState state; DN_NETResponseState state;
@@ -13627,6 +13792,7 @@ struct DN_NETEmcWSEvent
DN_NETEmcWSEvent *next; DN_NETEmcWSEvent *next;
}; };
typedef struct DN_NETEmcCore DN_NETEmcCore;
struct DN_NETEmcCore struct DN_NETEmcCore
{ {
DN_Pool pool; DN_Pool pool;
@@ -13634,6 +13800,7 @@ struct DN_NETEmcCore
DN_NETRequest *free_list; // Request pool that new requests will use before allocating DN_NETRequest *free_list; // Request pool that new requests will use before allocating
}; };
typedef struct DN_NETEmcRequest DN_NETEmcRequest;
struct DN_NETEmcRequest struct DN_NETEmcRequest
{ {
int socket; int socket;
+295 -119
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -65,7 +65,7 @@ static void AppendCppFileLineByLine(DN_Str8Builder *dest, DN_Str8 cpp_path)
line = DN_Str8FromFmtArena(&scratch.arena, "%S// DN: Single header generator commented out => %S", find.start_to_before_match, DN_Str8TrimWhitespaceAround(find.match_to_end_of_buffer)); line = DN_Str8FromFmtArena(&scratch.arena, "%S// DN: Single header generator commented out => %S", find.start_to_before_match, DN_Str8TrimWhitespaceAround(find.match_to_end_of_buffer));
DN_Str8 rel_include_path = DN_Str8TrimWhitespaceAround(find.after_match_to_end_of_buffer); DN_Str8 rel_include_path = DN_Str8TrimWhitespaceAround(find.after_match_to_end_of_buffer);
DN_Str8 root_dir = DN_Str8FileDirectoryFromPath(cpp_path); DN_Str8 root_dir = DN_Str8FileDirectoryFromPath(cpp_path);
extra_include_path = DN_OS_PathF(&scratch.arena, "%S/%S", root_dir, DN_Str8TrimSuffixSensitive(rel_include_path, DN_Str8Lit("\""))); extra_include_path = DN_OS_PathFmtArena(&scratch.arena, "%S/%S", root_dir, DN_Str8TrimSuffixSensitive(rel_include_path, DN_Str8Lit("\"")));
} }
} }
} }
@@ -113,7 +113,7 @@ int main(int argc, char **argv)
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena); DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
DN_Str8 suffix = type == FileType_Header ? DN_Str8Lit("h") : DN_Str8Lit("cpp"); DN_Str8 suffix = type == FileType_Header ? DN_Str8Lit("h") : DN_Str8Lit("cpp");
for (DN_ForItCArray(it, DN_Str8 const, REL_FILE_PATHS)) { for (DN_ForItCArray(it, DN_Str8 const, REL_FILE_PATHS)) {
DN_Str8 path = DN_OS_PathF(&scratch.arena, "%S/%S.%S", dn_root_dir, *it.data, suffix); DN_Str8 path = DN_OS_PathFmtArena(&scratch.arena, "%S/%S.%S", dn_root_dir, *it.data, suffix);
AppendCppFileLineByLine(&builder, path); AppendCppFileLineByLine(&builder, path);
} }
@@ -121,7 +121,7 @@ int main(int argc, char **argv)
DN_Str8BuilderPrependF(&builder, "// Generated by the DN single header generator %04u-%02u-%02u %02u:%02u:%02u\n\n", date.year, date.month, date.day, date.hour, date.minutes, date.seconds); DN_Str8BuilderPrependF(&builder, "// Generated by the DN single header generator %04u-%02u-%02u %02u:%02u:%02u\n\n", date.year, date.month, date.day, date.hour, date.minutes, date.seconds);
DN_Str8 buffer = DN_Str8TrimWhitespaceAround(DN_Str8FromStr8BuilderArena(&builder, &scratch.arena)); DN_Str8 buffer = DN_Str8TrimWhitespaceAround(DN_Str8FromStr8BuilderArena(&builder, &scratch.arena));
DN_Str8 single_header_path = DN_OS_PathF(&scratch.arena, "%S/dn_single_header.%S", output_dir, suffix); DN_Str8 single_header_path = DN_OS_PathFmtArena(&scratch.arena, "%S/dn_single_header.%S", output_dir, suffix);
DN_ErrSink *err = DN_TCErrSinkBeginDefault(); DN_ErrSink *err = DN_TCErrSinkBeginDefault();
DN_OS_FileWriteAllSafe(single_header_path, buffer, err); DN_OS_FileWriteAllSafe(single_header_path, buffer, err);
DN_ErrSinkEndExitIfErrorF(err, -1, "Failed to write Single header file '%S'", single_header_path); DN_ErrSinkEndExitIfErrorF(err, -1, "Failed to write Single header file '%S'", single_header_path);