Created
December 14, 2016 04:53
-
-
Save Sibras/6792316413f3a595d8a941d924cbe653 to your computer and use it in GitHub Desktop.
[PATCH 1/3] avutil/thread: Add pthread_cond_timedwait function.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From f4a48300bf545227b5fb9121bf46a95f40e8923a Mon Sep 17 00:00:00 2001 | |
From: Matt Oliver <protogonoi@gmail.com> | |
Date: Wed, 7 Dec 2016 16:55:35 +1100 | |
Subject: [PATCH 1/3] avutil/thread: Add pthread_cond_timedwait function. | |
Signed-off-by: Matt Oliver <protogonoi@gmail.com> | |
--- | |
compat/os2threads.h | 24 ++++++++++++++++++++++++ | |
compat/w32pthreads.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ | |
libavutil/thread.h | 6 ++++++ | |
3 files changed, 80 insertions(+) | |
diff --git a/compat/os2threads.h b/compat/os2threads.h | |
index 40a119f..a8b7824 100644 | |
--- a/compat/os2threads.h | |
+++ b/compat/os2threads.h | |
@@ -31,11 +31,13 @@ | |
#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/time.h" | |
typedef struct { | |
TID tid; | |
@@ -161,6 +163,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_nsec * 1000LL + abstime->tv_nsec / 1.0e6; | |
+ ULONG t = FFMAX(abs_milli - av_gettime(), 0LL); | |
+ | |
+ __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) | |
{ | |
diff --git a/compat/w32pthreads.h b/compat/w32pthreads.h | |
index 4ac2a99..abd54b2 100644 | |
--- a/compat/w32pthreads.h | |
+++ b/compat/w32pthreads.h | |
@@ -38,6 +38,7 @@ | |
#define WIN32_LEAN_AND_MEAN | |
#include <windows.h> | |
#include <process.h> | |
+#include <time.h> | |
#if _WIN32_WINNT < 0x0600 && defined(__MINGW32__) | |
#undef MemoryBarrier | |
@@ -48,6 +49,7 @@ | |
#include "libavutil/common.h" | |
#include "libavutil/internal.h" | |
#include "libavutil/mem.h" | |
+#include "libavutil/time.h" | |
typedef struct pthread_t { | |
void *handle; | |
@@ -171,6 +173,17 @@ static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex | |
return 0; | |
} | |
+static inline int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, | |
+ const struct timespec *abstime) | |
+{ | |
+ int64_t abs_milli = abstime->tv_nsec * 1000LL + abstime->tv_nsec / 1.0e6; | |
+ DWORD t = FFMAX(abs_milli - av_gettime(), 0LL); | |
+ | |
+ if (SleepConditionVariableCS(cond, mutex, t) == WAIT_TIMEOUT) | |
+ return ETIMEDOUT; | |
+ return 0; | |
+} | |
+ | |
static inline int pthread_cond_signal(pthread_cond_t *cond) | |
{ | |
WakeConditionVariable(cond); | |
@@ -367,6 +380,45 @@ static av_unused int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mu | |
return pthread_mutex_lock(mutex); | |
} | |
+static inline int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, | |
+ const struct timespec *abstime) | |
+{ | |
+ win32_cond_t *win32_cond = cond->Ptr; | |
+ int last_waiter; | |
+ int64_t abs_milli = abstime->tv_nsec * 1000LL + abstime->tv_nsec / 1.0e6; | |
+ DWORD t = FFMAX(abs_milli - av_gettime(), 0LL); | |
+ if (cond_wait) { | |
+ if (cond_wait(cond, mutex, t) == WAIT_TIMEOUT) | |
+ return ETIMEDOUT; | |
+ return 0; | |
+ } | |
+ | |
+ /* non native condition variables */ | |
+ pthread_mutex_lock(&win32_cond->mtx_broadcast); | |
+ pthread_mutex_lock(&win32_cond->mtx_waiter_count); | |
+ win32_cond->waiter_count++; | |
+ pthread_mutex_unlock(&win32_cond->mtx_waiter_count); | |
+ pthread_mutex_unlock(&win32_cond->mtx_broadcast); | |
+ | |
+ // unlock the external mutex | |
+ pthread_mutex_unlock(mutex); | |
+ DWORD ret = WaitForSingleObject(win32_cond->semaphore, t); | |
+ | |
+ pthread_mutex_lock(&win32_cond->mtx_waiter_count); | |
+ win32_cond->waiter_count--; | |
+ last_waiter = !win32_cond->waiter_count || !win32_cond->is_broadcast; | |
+ pthread_mutex_unlock(&win32_cond->mtx_waiter_count); | |
+ | |
+ if (last_waiter) | |
+ SetEvent(win32_cond->waiters_done); | |
+ | |
+ // lock the external mutex | |
+ pthread_mutex_lock(mutex); | |
+ | |
+ return (ret == WAIT_TIMEOUT) ? ETIMEDOUT : 0; | |
+} | |
+ | |
static av_unused int pthread_cond_signal(pthread_cond_t *cond) | |
{ | |
win32_cond_t *win32_cond = cond->Ptr; | |
diff --git a/libavutil/thread.h b/libavutil/thread.h | |
index 32ddf40..9d611f2 100644 | |
--- a/libavutil/thread.h | |
+++ b/libavutil/thread.h | |
@@ -108,6 +108,12 @@ static inline int strict_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t | |
ASSERT_PTHREAD(pthread_cond_wait, cond, mutex); | |
} | |
+static inline int strict_pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, | |
+ const struct timespec *abstime) | |
+{ | |
+ ASSERT_PTHREAD(pthread_cond_timedwait, cond, mutex, abstime); | |
+} | |
+ | |
static inline int strict_pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) | |
{ | |
ASSERT_PTHREAD(pthread_once, once_control, init_routine); | |
-- | |
2.10.2.windows.1 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment