More posix fixes

This commit is contained in:
doylet 2025-06-08 19:21:38 +10:00
parent 842085ac26
commit 4852a431a8
6 changed files with 33 additions and 35 deletions

View File

@ -495,7 +495,7 @@ DN_API bool DN_TicketMutex_CanLock (DN_TicketMutex const *mutex, DN_UInt t
((list) && ((list) != (list)->next)) ((list) && ((list) != (list)->next))
#define DN_DLList_ForEach(it, list) \ #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 //////////////////////////////////////////////////////////////////////////////// // NOTE: Intrinsics ////////////////////////////////////////////////////////////////////////////////
DN_FORCE_INLINE DN_U64 DN_Atomic_SetValue64(DN_U64 volatile *target, DN_U64 value) DN_FORCE_INLINE DN_U64 DN_Atomic_SetValue64(DN_U64 volatile *target, DN_U64 value)

View File

@ -1703,7 +1703,7 @@ static DN_UTCore DN_Tests_OS()
DN_U64 end = DN_OS_PerfCounterNow(); DN_U64 end = DN_OS_PerfCounterNow();
DN_UT_AssertF(&result, wait_result == DN_OSSemaphoreWaitResult_Timeout, "Received wait result %zu", wait_result); 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_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") 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_OS_ConditionVariableWait(&cv, &mutex, 100 /*sleep_ms*/);
DN_U64 end = DN_OS_PerfCounterNow(); DN_U64 end = DN_OS_PerfCounterNow();
DN_F64 elapsed_ms = DN_OS_PerfCounterMs(begin, end); 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_MutexDeinit(&mutex);
DN_OS_ConditionVariableDeinit(&cv); DN_OS_ConditionVariableDeinit(&cv);

View File

@ -129,6 +129,10 @@ DN_API void DN_OS_Init(DN_OSCore *os, DN_OSInitArgs *args)
w32->bcrypt_init_success = true; w32->bcrypt_init_success = true;
else else
DN_LOG_ErrorF("Failed to initialise Windows secure random number generator, error: %d", init_status); 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 #endif
} }
@ -261,12 +265,6 @@ DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8Now(char date_separator, char hm
return result; 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) DN_API bool DN_OS_DateIsValid(DN_OSDateTime date)
{ {
if (date.year < 1970) if (date.year < 1970)

View File

@ -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_OSDateTimeStr8 DN_OS_DateLocalTimeStr8 (DN_OSDateTime time, char date_separator = '-', char hms_separator = ':');
DN_API DN_U64 DN_OS_DateUnixTimeNs (); DN_API DN_U64 DN_OS_DateUnixTimeNs ();
#define DN_OS_DateUnixTimeUs() (DN_OS_DateUnixTimeNs() / 1000) #define DN_OS_DateUnixTimeUs() (DN_OS_DateUnixTimeNs() / 1000)
#define DN_OS_DateUnixTimeMs() (DN_OS_DateUnixTimeNs() / 1000 * 1000) #define DN_OS_DateUnixTimeMs() (DN_OS_DateUnixTimeNs() / (1000 * 1000))
DN_API DN_U64 DN_OS_DateUnixTimeS (); #define DN_OS_DateUnixTimeS() (DN_OS_DateUnixTimeNs() / (1000 * 1000 * 1000))
DN_API DN_OSDateTime DN_OS_DateUnixTimeSToDate (DN_U64 time); 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_DateLocalToUnixTimeS(DN_OSDateTime date);
DN_API DN_U64 DN_OS_DateToUnixTimeS (DN_OSDateTime date); DN_API DN_U64 DN_OS_DateToUnixTimeS (DN_OSDateTime date);

View File

@ -1052,9 +1052,6 @@ static void DN_POSIX_DeallocSyncPrimitive_(DN_POSIXSyncPrimitive *primitive)
// NOTE: DN_OSSemaphore //////////////////////////////////////////////////////////////////////////// // NOTE: DN_OSSemaphore ////////////////////////////////////////////////////////////////////////////
DN_API DN_OSSemaphore DN_OS_SemaphoreInit(DN_U32 initial_count) 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_OSSemaphore result = {};
DN_POSIXSyncPrimitive *primitive = DN_POSIX_AllocSyncPrimitive_(); DN_POSIXSyncPrimitive *primitive = DN_POSIX_AllocSyncPrimitive_();
if (primitive) { 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) 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); DN_POSIXSyncPrimitive *primitive = DN_OS_U64ToPOSIXSyncPrimitive_(semaphore->handle);
sem_destroy(&primitive->sem); sem_destroy(&primitive->sem);
DN_POSIX_DeallocSyncPrimitive_(posix_sem); DN_POSIX_DeallocSyncPrimitive_(primitive);
*semaphore = {}; *semaphore = {};
} }
} }
DN_API void DN_OS_SemaphoreIncrement(DN_OSSemaphore *semaphore, DN_U32 amount) 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); DN_POSIXSyncPrimitive *primitive = DN_OS_U64ToPOSIXSyncPrimitive_(semaphore->handle);
#if defined(DN_OS_WIN32) #if defined(DN_OS_WIN32)
sem_post_multiple(&primitive->sem, amount); // mingw extension 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_U32 timeout_ms)
{ {
DN_OSSemaphoreWaitResult result = {}; DN_OSSemaphoreWaitResult result = {};
if (semaphore.handle == 0) if (!semaphore || semaphore->handle == 0)
return result; return result;
DN_POSIXSyncPrimitive *primitive = DN_OS_U64ToPOSIXSyncPrimitive_(semaphore->handle); 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) if (wait_result == 0)
result = DN_OSSemaphoreWaitResult_Success; result = DN_OSSemaphoreWaitResult_Success;
} else { } else {
DN_U64 now_ms = DN_OS_DateUnixTimeMs();
DN_U64 end_ts_ms = now_ms + timeout_ms;
struct timespec abs_timeout = {}; struct timespec abs_timeout = {};
abs_timeout.tv_sec = timeout_ms / 1000; abs_timeout.tv_sec = end_ts_ms / 1'000;
abs_timeout.tv_nsec = (timeout_ms % 1000) * 1'000'000; abs_timeout.tv_nsec = 1'000'000 * (end_ts_ms - (end_ts_ms / 1'000) * 1'000);
if (sem_timedwait(&primitive->sem) == 0) if (sem_timedwait(&primitive->sem, &abs_timeout) == 0)
result = DN_OSSemaphoreWaitResult_Success; result = DN_OSSemaphoreWaitResult_Success;
else if (errno == ETIMEDOUT) else if (errno == ETIMEDOUT)
result = DN_OSSemaphoreWaitResult_Timeout; result = DN_OSSemaphoreWaitResult_Timeout;
@ -1121,11 +1121,10 @@ DN_API DN_OSSemaphoreWaitResult DN_OS_SemaphoreWait(DN_OSSemaphore *semaphore,
// NOTE: DN_OSMutex //////////////////////////////////////////////////////////////////////////////// // NOTE: DN_OSMutex ////////////////////////////////////////////////////////////////////////////////
DN_API DN_OSMutex DN_OS_MutexInit() DN_API DN_OSMutex DN_OS_MutexInit()
{ {
DN_W32SyncPrimitive *primitive = DN_W32_AllocSyncPrimitive_(); DN_POSIXSyncPrimitive *primitive = DN_POSIX_AllocSyncPrimitive_();
DN_OSMutex result = {}; DN_OSMutex result = {};
if (primitive) { if (primitive) {
int pshared = 0; // Share the semaphore across all threads in the process if (pthread_mutex_init(&primitive->mutex, nullptr) == 0)
if (pthread_mutex_init(mutex, pshared, nullptr) == 0)
result.handle = DN_POSIX_SyncPrimitiveToU64(primitive); result.handle = DN_POSIX_SyncPrimitiveToU64(primitive);
else else
DN_POSIX_DeallocSyncPrimitive_(primitive); DN_POSIX_DeallocSyncPrimitive_(primitive);
@ -1136,7 +1135,7 @@ DN_API DN_OSMutex DN_OS_MutexInit()
DN_API void DN_OS_MutexDeinit(DN_OSMutex *mutex) DN_API void DN_OS_MutexDeinit(DN_OSMutex *mutex)
{ {
if (mutex && mutex->handle != 0) { 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); pthread_mutex_destroy(&primitive->mutex);
DN_POSIX_DeallocSyncPrimitive_(primitive); DN_POSIX_DeallocSyncPrimitive_(primitive);
*mutex = {}; *mutex = {};
@ -1146,7 +1145,7 @@ DN_API void DN_OS_MutexDeinit(DN_OSMutex *mutex)
DN_API void DN_OS_MutexLock(DN_OSMutex *mutex) DN_API void DN_OS_MutexLock(DN_OSMutex *mutex)
{ {
if (mutex && mutex->handle != 0) { 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); 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) DN_API void DN_OS_MutexUnlock(DN_OSMutex *mutex)
{ {
if (mutex && mutex->handle != 0) { 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); pthread_mutex_unlock(&primitive->mutex);
} }
} }
@ -1164,7 +1163,7 @@ DN_API DN_OSConditionVariable DN_OS_ConditionVariableInit()
DN_POSIXSyncPrimitive *primitive = DN_POSIX_AllocSyncPrimitive_(); DN_POSIXSyncPrimitive *primitive = DN_POSIX_AllocSyncPrimitive_();
DN_OSConditionVariable result = {}; DN_OSConditionVariable result = {};
if (primitive) { if (primitive) {
if (pthread_cond_init(&primitive->cv) == 0) if (pthread_cond_init(&primitive->cv, nullptr) == 0)
result.handle = DN_POSIX_SyncPrimitiveToU64(primitive); result.handle = DN_POSIX_SyncPrimitiveToU64(primitive);
else else
DN_POSIX_DeallocSyncPrimitive_(primitive); DN_POSIX_DeallocSyncPrimitive_(primitive);
@ -1172,7 +1171,7 @@ DN_API DN_OSConditionVariable DN_OS_ConditionVariableInit()
return result; 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) { if (cv && cv->handle != 0) {
DN_POSIXSyncPrimitive *primitive = DN_OS_U64ToPOSIXSyncPrimitive_(cv->handle); 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 *cv_primitive = DN_OS_U64ToPOSIXSyncPrimitive_(cv->handle);
DN_POSIXSyncPrimitive *mutex_primitive = DN_OS_U64ToPOSIXSyncPrimitive_(mutex->handle); DN_POSIXSyncPrimitive *mutex_primitive = DN_OS_U64ToPOSIXSyncPrimitive_(mutex->handle);
struct timespec time; struct timespec time = {};
time.tv_sec = end_ts_ms / 1'000; time.tv_sec = end_ts_ms / 1'000;
time.tv_nsec = 1'000'000 * (end_ts_ms - (end_ts_ms / 1'000) * 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); int wait_result = pthread_cond_timedwait(&cv_primitive->cv, &mutex_primitive->mutex, &time);
result = (wait_result != ETIMEDOUT); result = (wait_result != ETIMEDOUT);
} }
return result; return result;
} }

View File

@ -69,6 +69,7 @@ struct DN_POSIXSyncPrimitive
struct DN_POSIXCore struct DN_POSIXCore
{ {
DN_POSIXSyncPrimitive *sync_primitive_free_list; DN_POSIXSyncPrimitive *sync_primitive_free_list;
pthread_mutex_t sync_primitive_free_list_mutex;
}; };
DN_API void DN_Posix_ThreadSetName(DN_Str8 name); DN_API void DN_Posix_ThreadSetName(DN_Str8 name);