]> git.sesse.net Git - ffmpeg/blobdiff - compat/os2threads.h
avutil/thread: Add pthread_cond_timedwait function
[ffmpeg] / compat / os2threads.h
index 2177a033ecbb029aa0a3855a360e4123fb920d20..eec6f40ae72c2a6552f1bcb0f055928c7cc29819 100644 (file)
 
 #undef __STRICT_ANSI__          /* for _beginthread() */
 #include <stdlib.h>
+#include <time.h>
 
 #include <sys/builtin.h>
 #include <sys/fmutex.h>
 
 #include "libavutil/attributes.h"
+#include "libavutil/common.h"
+#include "libavutil/time.h"
 
 typedef struct {
     TID tid;
@@ -163,6 +166,28 @@ static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
     return 0;
 }
 
+static av_always_inline int pthread_cond_timedwait(pthread_cond_t *cond,
+                                                   pthread_mutex_t *mutex,
+                                                   const struct timespec *abstime)
+{
+    int64_t abs_milli = abstime->tv_sec * 1000LL + abstime->tv_nsec / 1000000;
+    ULONG t = av_clip64(abs_milli - av_gettime() / 1000, 0, ULONG_MAX);
+
+    __atomic_increment(&cond->wait_count);
+
+    pthread_mutex_unlock(mutex);
+
+    APIRET ret = DosWaitEventSem(cond->event_sem, t);
+
+    __atomic_decrement(&cond->wait_count);
+
+    DosPostEventSem(cond->ack_sem);
+
+    pthread_mutex_lock(mutex);
+
+    return (ret == ERROR_TIMEOUT) ? ETIMEDOUT : 0;
+}
+
 static av_always_inline int pthread_cond_wait(pthread_cond_t *cond,
                                               pthread_mutex_t *mutex)
 {