Message ID | CAHVN4mhVtUcDKquiJnooBkav5QMLtsZCFmHmvsPpKNPwce2fmw@mail.gmail.com |
---|---|
State | Accepted |
Headers | show |
On Wed, Dec 7, 2016 at 7:04 AM, Matt Oliver <protogonoi@gmail.com> wrote: > 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,43 @@ 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) { > + cond_wait(cond, mutex, t); > + return 0; This does not return any error codes like the other implementations. > + } > + > + /* 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 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel >
On 7 December 2016 at 21:32, Hendrik Leppkes <h.leppkes@gmail.com> wrote: > On Wed, Dec 7, 2016 at 7:04 AM, Matt Oliver <protogonoi@gmail.com> wrote: > > 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,43 @@ 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) { > > + cond_wait(cond, mutex, t); > > + return 0; > > This does not return any error codes like the other implementations. > fixed locally be changing to: + if (cond_wait) { + if (cond_wait(cond, mutex, t) == WAIT_TIMEOUT) + return ETIMEDOUT; + return 0;
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,43 @@ 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) { + cond_wait(cond, mutex, t); + 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); +} +
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(+) static inline int strict_pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) { ASSERT_PTHREAD(pthread_once, once_control, init_routine);