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))
#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)

View File

@ -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);

View File

@ -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)

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_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);

View File

@ -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;
}

View File

@ -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);