From 4852a431a8f3a3f6e360a10706252018fe14e0e0 Mon Sep 17 00:00:00 2001 From: doylet Date: Sun, 8 Jun 2025 19:21:38 +1000 Subject: [PATCH] More posix fixes --- Base/dn_base.h | 2 +- Extra/dn_tests.cpp | 4 ++-- OS/dn_os.cpp | 10 ++++------ OS/dn_os.h | 4 ++-- OS/dn_os_posix.cpp | 47 +++++++++++++++++++++++----------------------- OS/dn_os_posix.h | 1 + 6 files changed, 33 insertions(+), 35 deletions(-) diff --git a/Base/dn_base.h b/Base/dn_base.h index 98edb98..ac0a72f 100644 --- a/Base/dn_base.h +++ b/Base/dn_base.h @@ -495,7 +495,7 @@ DN_API bool DN_TicketMutex_CanLock (DN_TicketMutex const *mutex, DN_UInt t ((list) && ((list) != (list)->next)) #define DN_DLList_ForEach(it, list) \ - auto *it = (list)->next; (it) != (list); (it) = (it)->next \ + auto *it = (list)->next; (it) != (list); (it) = (it)->next // NOTE: Intrinsics //////////////////////////////////////////////////////////////////////////////// DN_FORCE_INLINE DN_U64 DN_Atomic_SetValue64(DN_U64 volatile *target, DN_U64 value) diff --git a/Extra/dn_tests.cpp b/Extra/dn_tests.cpp index e3e3ff4..2bfb8d9 100644 --- a/Extra/dn_tests.cpp +++ b/Extra/dn_tests.cpp @@ -1703,7 +1703,7 @@ static DN_UTCore DN_Tests_OS() DN_U64 end = DN_OS_PerfCounterNow(); DN_UT_AssertF(&result, wait_result == DN_OSSemaphoreWaitResult_Timeout, "Received wait result %zu", wait_result); DN_F64 elapsed_ms = DN_OS_PerfCounterMs(begin, end); - DN_UT_AssertF(&result, elapsed_ms >= 100, "Expected to sleep for >= 100ms, slept %f ms", elapsed_ms); + DN_UT_AssertF(&result, elapsed_ms >= 99 && elapsed_ms <= 120, "Expected to sleep for ~100ms, slept %f ms", elapsed_ms); } DN_UT_Test(&result, "Wait success") @@ -1737,7 +1737,7 @@ static DN_UTCore DN_Tests_OS() DN_OS_ConditionVariableWait(&cv, &mutex, 100 /*sleep_ms*/); DN_U64 end = DN_OS_PerfCounterNow(); DN_F64 elapsed_ms = DN_OS_PerfCounterMs(begin, end); - DN_UT_AssertF(&result, elapsed_ms >= 100, "Expected to sleep for >= 100ms, slept %f ms", elapsed_ms); + DN_UT_AssertF(&result, elapsed_ms >= 99 && elapsed_ms <= 120, "Expected to sleep for ~100ms, slept %f ms", elapsed_ms); } DN_OS_MutexDeinit(&mutex); DN_OS_ConditionVariableDeinit(&cv); diff --git a/OS/dn_os.cpp b/OS/dn_os.cpp index afebc16..41f8ceb 100644 --- a/OS/dn_os.cpp +++ b/OS/dn_os.cpp @@ -129,6 +129,10 @@ DN_API void DN_OS_Init(DN_OSCore *os, DN_OSInitArgs *args) w32->bcrypt_init_success = true; else DN_LOG_ErrorF("Failed to initialise Windows secure random number generator, error: %d", init_status); + #else + DN_POSIXCore *posix = DN_CAST(DN_POSIXCore *) os->platform_context; + int mutex_init = pthread_mutex_init(&posix->sync_primitive_free_list_mutex, nullptr); + DN_Assert(mutex_init == 0); #endif } @@ -261,12 +265,6 @@ DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8Now(char date_separator, char hm return result; } -DN_API uint64_t DN_OS_DateUnixTimeS() -{ - uint64_t result = DN_OS_DateUnixTimeNs() / (1'000 /*us*/ * 1'000 /*ms*/ * 1'000 /*s*/); - return result; -} - DN_API bool DN_OS_DateIsValid(DN_OSDateTime date) { if (date.year < 1970) diff --git a/OS/dn_os.h b/OS/dn_os.h index bcf0a8b..6fce49b 100644 --- a/OS/dn_os.h +++ b/OS/dn_os.h @@ -333,8 +333,8 @@ DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8Now(char date_separator DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8 (DN_OSDateTime time, char date_separator = '-', char hms_separator = ':'); DN_API DN_U64 DN_OS_DateUnixTimeNs (); #define DN_OS_DateUnixTimeUs() (DN_OS_DateUnixTimeNs() / 1000) -#define DN_OS_DateUnixTimeMs() (DN_OS_DateUnixTimeNs() / 1000 * 1000) -DN_API DN_U64 DN_OS_DateUnixTimeS (); +#define DN_OS_DateUnixTimeMs() (DN_OS_DateUnixTimeNs() / (1000 * 1000)) +#define DN_OS_DateUnixTimeS() (DN_OS_DateUnixTimeNs() / (1000 * 1000 * 1000)) DN_API DN_OSDateTime DN_OS_DateUnixTimeSToDate (DN_U64 time); DN_API DN_U64 DN_OS_DateLocalToUnixTimeS(DN_OSDateTime date); DN_API DN_U64 DN_OS_DateToUnixTimeS (DN_OSDateTime date); diff --git a/OS/dn_os_posix.cpp b/OS/dn_os_posix.cpp index 0c9fe89..cbcc753 100644 --- a/OS/dn_os_posix.cpp +++ b/OS/dn_os_posix.cpp @@ -1052,9 +1052,6 @@ static void DN_POSIX_DeallocSyncPrimitive_(DN_POSIXSyncPrimitive *primitive) // NOTE: DN_OSSemaphore //////////////////////////////////////////////////////////////////////////// DN_API DN_OSSemaphore DN_OS_SemaphoreInit(DN_U32 initial_count) { - DN_POSIXCore *posix = g_dn_os_core->posix_context; - DN_Assert(posix); - DN_OSSemaphore result = {}; DN_POSIXSyncPrimitive *primitive = DN_POSIX_AllocSyncPrimitive_(); if (primitive) { @@ -1069,17 +1066,17 @@ DN_API DN_OSSemaphore DN_OS_SemaphoreInit(DN_U32 initial_count) DN_API void DN_OS_SemaphoreDeinit(DN_OSSemaphore *semaphore) { - if (semaphore.handle != 0) { + if (semaphore && semaphore->handle != 0) { DN_POSIXSyncPrimitive *primitive = DN_OS_U64ToPOSIXSyncPrimitive_(semaphore->handle); sem_destroy(&primitive->sem); - DN_POSIX_DeallocSyncPrimitive_(posix_sem); + DN_POSIX_DeallocSyncPrimitive_(primitive); *semaphore = {}; } } DN_API void DN_OS_SemaphoreIncrement(DN_OSSemaphore *semaphore, DN_U32 amount) { - if (semaphore.handle != 0) { + if (semaphore && semaphore->handle != 0) { DN_POSIXSyncPrimitive *primitive = DN_OS_U64ToPOSIXSyncPrimitive_(semaphore->handle); #if defined(DN_OS_WIN32) sem_post_multiple(&primitive->sem, amount); // mingw extension @@ -1094,7 +1091,7 @@ DN_API DN_OSSemaphoreWaitResult DN_OS_SemaphoreWait(DN_OSSemaphore *semaphore, DN_U32 timeout_ms) { DN_OSSemaphoreWaitResult result = {}; - if (semaphore.handle == 0) + if (!semaphore || semaphore->handle == 0) return result; DN_POSIXSyncPrimitive *primitive = DN_OS_U64ToPOSIXSyncPrimitive_(semaphore->handle); @@ -1107,10 +1104,13 @@ DN_API DN_OSSemaphoreWaitResult DN_OS_SemaphoreWait(DN_OSSemaphore *semaphore, if (wait_result == 0) result = DN_OSSemaphoreWaitResult_Success; } else { + DN_U64 now_ms = DN_OS_DateUnixTimeMs(); + DN_U64 end_ts_ms = now_ms + timeout_ms; + struct timespec abs_timeout = {}; - abs_timeout.tv_sec = timeout_ms / 1000; - abs_timeout.tv_nsec = (timeout_ms % 1000) * 1'000'000; - if (sem_timedwait(&primitive->sem) == 0) + abs_timeout.tv_sec = end_ts_ms / 1'000; + abs_timeout.tv_nsec = 1'000'000 * (end_ts_ms - (end_ts_ms / 1'000) * 1'000); + if (sem_timedwait(&primitive->sem, &abs_timeout) == 0) result = DN_OSSemaphoreWaitResult_Success; else if (errno == ETIMEDOUT) result = DN_OSSemaphoreWaitResult_Timeout; @@ -1121,11 +1121,10 @@ DN_API DN_OSSemaphoreWaitResult DN_OS_SemaphoreWait(DN_OSSemaphore *semaphore, // NOTE: DN_OSMutex //////////////////////////////////////////////////////////////////////////////// DN_API DN_OSMutex DN_OS_MutexInit() { - DN_W32SyncPrimitive *primitive = DN_W32_AllocSyncPrimitive_(); - DN_OSMutex result = {}; + DN_POSIXSyncPrimitive *primitive = DN_POSIX_AllocSyncPrimitive_(); + DN_OSMutex result = {}; if (primitive) { - int pshared = 0; // Share the semaphore across all threads in the process - if (pthread_mutex_init(mutex, pshared, nullptr) == 0) + if (pthread_mutex_init(&primitive->mutex, nullptr) == 0) result.handle = DN_POSIX_SyncPrimitiveToU64(primitive); else DN_POSIX_DeallocSyncPrimitive_(primitive); @@ -1136,7 +1135,7 @@ DN_API DN_OSMutex DN_OS_MutexInit() DN_API void DN_OS_MutexDeinit(DN_OSMutex *mutex) { if (mutex && mutex->handle != 0) { - DN_POSIXSyncPrimitive *primitive = DN_OS_U64ToPOSIXSyncPrimitive_(semaphore->handle); + DN_POSIXSyncPrimitive *primitive = DN_OS_U64ToPOSIXSyncPrimitive_(mutex->handle); pthread_mutex_destroy(&primitive->mutex); DN_POSIX_DeallocSyncPrimitive_(primitive); *mutex = {}; @@ -1146,7 +1145,7 @@ DN_API void DN_OS_MutexDeinit(DN_OSMutex *mutex) DN_API void DN_OS_MutexLock(DN_OSMutex *mutex) { if (mutex && mutex->handle != 0) { - DN_POSIXSyncPrimitive *primitive = DN_OS_U64ToPOSIXSyncPrimitive_(semaphore->handle); + DN_POSIXSyncPrimitive *primitive = DN_OS_U64ToPOSIXSyncPrimitive_(mutex->handle); pthread_mutex_lock(&primitive->mutex); } } @@ -1154,7 +1153,7 @@ DN_API void DN_OS_MutexLock(DN_OSMutex *mutex) DN_API void DN_OS_MutexUnlock(DN_OSMutex *mutex) { if (mutex && mutex->handle != 0) { - DN_POSIXSyncPrimitive *primitive = DN_OS_U64ToPOSIXSyncPrimitive_(semaphore->handle); + DN_POSIXSyncPrimitive *primitive = DN_OS_U64ToPOSIXSyncPrimitive_(mutex->handle); pthread_mutex_unlock(&primitive->mutex); } } @@ -1164,7 +1163,7 @@ DN_API DN_OSConditionVariable DN_OS_ConditionVariableInit() DN_POSIXSyncPrimitive *primitive = DN_POSIX_AllocSyncPrimitive_(); DN_OSConditionVariable result = {}; if (primitive) { - if (pthread_cond_init(&primitive->cv) == 0) + if (pthread_cond_init(&primitive->cv, nullptr) == 0) result.handle = DN_POSIX_SyncPrimitiveToU64(primitive); else DN_POSIX_DeallocSyncPrimitive_(primitive); @@ -1172,7 +1171,7 @@ DN_API DN_OSConditionVariable DN_OS_ConditionVariableInit() return result; } -DN_API bool DN_OS_ConditionVariableDeinit(DN_OSConditionVariable *cv) +DN_API void DN_OS_ConditionVariableDeinit(DN_OSConditionVariable *cv) { if (cv && cv->handle != 0) { DN_POSIXSyncPrimitive *primitive = DN_OS_U64ToPOSIXSyncPrimitive_(cv->handle); @@ -1189,11 +1188,11 @@ DN_API bool DN_OS_ConditionVariableWaitUntil(DN_OSConditionVariable *cv, DN_OSMu DN_POSIXSyncPrimitive *cv_primitive = DN_OS_U64ToPOSIXSyncPrimitive_(cv->handle); DN_POSIXSyncPrimitive *mutex_primitive = DN_OS_U64ToPOSIXSyncPrimitive_(mutex->handle); - struct timespec time; - time.tv_sec = end_ts_ms / 1'000; - time.tv_nsec = 1'000'000 * (end_ts_ms - (end_ts_ms / 1'000) * 1'000); - int wait_result = pthread_cond_timedwait(&cv_primitive->cv, &mutex_primitive->mutex, &time); - result = (wait_result != ETIMEDOUT); + struct timespec time = {}; + time.tv_sec = end_ts_ms / 1'000; + time.tv_nsec = 1'000'000 * (end_ts_ms - (end_ts_ms / 1'000) * 1'000); + int wait_result = pthread_cond_timedwait(&cv_primitive->cv, &mutex_primitive->mutex, &time); + result = (wait_result != ETIMEDOUT); } return result; } diff --git a/OS/dn_os_posix.h b/OS/dn_os_posix.h index 5ce3566..a8cc1fa 100644 --- a/OS/dn_os_posix.h +++ b/OS/dn_os_posix.h @@ -69,6 +69,7 @@ struct DN_POSIXSyncPrimitive struct DN_POSIXCore { DN_POSIXSyncPrimitive *sync_primitive_free_list; + pthread_mutex_t sync_primitive_free_list_mutex; }; DN_API void DN_Posix_ThreadSetName(DN_Str8 name);