diff options
-rw-r--r-- | includes/rts/OSThreads.h | 1 | ||||
-rw-r--r-- | rts/posix/OSThreads.c | 16 | ||||
-rw-r--r-- | rts/win32/OSThreads.c | 10 |
3 files changed, 27 insertions, 0 deletions
diff --git a/includes/rts/OSThreads.h b/includes/rts/OSThreads.h index 21b92950b2..ed9c0a3b5e 100644 --- a/includes/rts/OSThreads.h +++ b/includes/rts/OSThreads.h @@ -175,6 +175,7 @@ extern void closeCondition ( Condition* pCond ); extern bool broadcastCondition ( Condition* pCond ); extern bool signalCondition ( Condition* pCond ); extern bool waitCondition ( Condition* pCond, Mutex* pMut ); +extern bool timedWaitCondition ( Condition* pCond, Mutex* pMut, Time timeout); // // Mutexes diff --git a/rts/posix/OSThreads.c b/rts/posix/OSThreads.c index be2b596c35..200a4ccdad 100644 --- a/rts/posix/OSThreads.c +++ b/rts/posix/OSThreads.c @@ -78,6 +78,9 @@ #include <numa.h> #endif +// TODO does this need configure magic? +#include <time.h> + /* * This (allegedly) OS threads independent layer was initially * abstracted away from code that used Pthreads, so the functions @@ -117,6 +120,19 @@ waitCondition ( Condition* pCond, Mutex* pMut ) return (pthread_cond_wait(pCond,pMut) == 0); } +bool +timedWaitCondition ( Condition* pCond, Mutex* pMut, Time timeout) { + timeout += getMonotonicNSec(); + uint64_t secs = TimeToSeconds(timeout); + + const struct timespec t = (struct timespec) { + .tv_sec = secs, + .tv_nsec = TimeToNS(timeout - SecondsToTime(secs)) + }; + + return pthread_cond_timedwait(pCond,pMut, &t) == 0; +} + void yieldThread(void) { diff --git a/rts/win32/OSThreads.c b/rts/win32/OSThreads.c index ed8a598e51..07b0e3f034 100644 --- a/rts/win32/OSThreads.c +++ b/rts/win32/OSThreads.c @@ -559,6 +559,16 @@ waitCondition ( Condition* pCond, Mutex* pMut ) return true; } +bool +timedWaitCondition ( Condition* pCond, Mutex* pMut, Time timeout ) +{ + // If we pass a timeout of 0 SleepConditionVariableSRW will return immediately + // https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleepconditionvariablesrw + DWORD ms = (DWORD)stg_min(1, TimeToMS(timeout)); + SleepConditionVariableSRW(pCond, pMut, ms, 0); + return true; +} + void initMutex (Mutex* pMut) { |