Message ID | 20200120001430.28857-1-cus@passwd.hu |
---|---|
State | Accepted |
Headers | show |
Series | [FFmpeg-devel,PATCHv2] avutil/thread: Add pthread_cond_timedwait function | expand |
Context | Check | Description |
---|---|---|
andriy/ffmpeg-patchwork | success | Make fate finished |
On Mon, 20 Jan 2020 at 11:14, Marton Balint <cus@passwd.hu> wrote: > From: Matt Oliver <protogonoi@gmail.com> > > v2: fix calculating milisecond times and use SleepConditionVariableSRW. > > Signed-off-by: Matt Oliver <protogonoi@gmail.com> > --- > compat/os2threads.h | 25 +++++++++++++++++++++++++ > compat/w32pthreads.h | 18 ++++++++++++++++++ > libavutil/thread.h | 7 +++++++ > 3 files changed, 50 insertions(+) > > diff --git a/compat/os2threads.h b/compat/os2threads.h > index 2177a033ec..eec6f40ae7 100644 > --- a/compat/os2threads.h > +++ b/compat/os2threads.h > @@ -31,11 +31,14 @@ > > #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) > { > diff --git a/compat/w32pthreads.h b/compat/w32pthreads.h > index 21acfd2ba1..7df33b7da4 100644 > --- a/compat/w32pthreads.h > +++ b/compat/w32pthreads.h > @@ -38,11 +38,13 @@ > #define WIN32_LEAN_AND_MEAN > #include <windows.h> > #include <process.h> > +#include <time.h> > > #include "libavutil/attributes.h" > #include "libavutil/common.h" > #include "libavutil/internal.h" > #include "libavutil/mem.h" > +#include "libavutil/time.h" > > typedef struct pthread_t { > void *handle; > @@ -156,6 +158,22 @@ 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_sec * 1000LL + abstime->tv_nsec / > 1000000; > + DWORD t = av_clip64(abs_milli - av_gettime() / 1000, 0, UINT32_MAX); > + > + if (!SleepConditionVariableSRW(cond, mutex, t, 0)) { > + DWORD err = GetLastError(); > + if (err == ERROR_TIMEOUT) > + return ETIMEDOUT; > + else > + return EINVAL; > + } > + return 0; > +} > + > static inline int pthread_cond_signal(pthread_cond_t *cond) > { > WakeConditionVariable(cond); > diff --git a/libavutil/thread.h b/libavutil/thread.h > index cc5272d379..65b97ef303 100644 > --- a/libavutil/thread.h > +++ b/libavutil/thread.h > @@ -109,6 +109,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); > @@ -124,6 +130,7 @@ static inline int strict_pthread_once(pthread_once_t > *once_control, void (*init_ > #define pthread_cond_signal strict_pthread_cond_signal > #define pthread_cond_broadcast strict_pthread_cond_broadcast > #define pthread_cond_wait strict_pthread_cond_wait > +#define pthread_cond_timedwait strict_pthread_cond_timedwait > #define pthread_once strict_pthread_once > #endif > > -- > 2.16.4 > > lgtm
On Mon, 20 Jan 2020, Matt Oliver wrote: > On Mon, 20 Jan 2020 at 11:14, Marton Balint <cus@passwd.hu> wrote: > >> From: Matt Oliver <protogonoi@gmail.com> >> >> v2: fix calculating milisecond times and use SleepConditionVariableSRW. >> >> Signed-off-by: Matt Oliver <protogonoi@gmail.com> >> --- >> compat/os2threads.h | 25 +++++++++++++++++++++++++ >> compat/w32pthreads.h | 18 ++++++++++++++++++ >> libavutil/thread.h | 7 +++++++ >> 3 files changed, 50 insertions(+) >> >> diff --git a/compat/os2threads.h b/compat/os2threads.h >> index 2177a033ec..eec6f40ae7 100644 >> --- a/compat/os2threads.h >> +++ b/compat/os2threads.h >> @@ -31,11 +31,14 @@ >> >> #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) >> { >> diff --git a/compat/w32pthreads.h b/compat/w32pthreads.h >> index 21acfd2ba1..7df33b7da4 100644 >> --- a/compat/w32pthreads.h >> +++ b/compat/w32pthreads.h >> @@ -38,11 +38,13 @@ >> #define WIN32_LEAN_AND_MEAN >> #include <windows.h> >> #include <process.h> >> +#include <time.h> >> >> #include "libavutil/attributes.h" >> #include "libavutil/common.h" >> #include "libavutil/internal.h" >> #include "libavutil/mem.h" >> +#include "libavutil/time.h" >> >> typedef struct pthread_t { >> void *handle; >> @@ -156,6 +158,22 @@ 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_sec * 1000LL + abstime->tv_nsec / >> 1000000; >> + DWORD t = av_clip64(abs_milli - av_gettime() / 1000, 0, UINT32_MAX); >> + >> + if (!SleepConditionVariableSRW(cond, mutex, t, 0)) { >> + DWORD err = GetLastError(); >> + if (err == ERROR_TIMEOUT) >> + return ETIMEDOUT; >> + else >> + return EINVAL; >> + } >> + return 0; >> +} >> + >> static inline int pthread_cond_signal(pthread_cond_t *cond) >> { >> WakeConditionVariable(cond); >> diff --git a/libavutil/thread.h b/libavutil/thread.h >> index cc5272d379..65b97ef303 100644 >> --- a/libavutil/thread.h >> +++ b/libavutil/thread.h >> @@ -109,6 +109,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); >> @@ -124,6 +130,7 @@ static inline int strict_pthread_once(pthread_once_t >> *once_control, void (*init_ >> #define pthread_cond_signal strict_pthread_cond_signal >> #define pthread_cond_broadcast strict_pthread_cond_broadcast >> #define pthread_cond_wait strict_pthread_cond_wait >> +#define pthread_cond_timedwait strict_pthread_cond_timedwait >> #define pthread_once strict_pthread_once >> #endif >> >> -- >> 2.16.4 >> >> > lgtm Thanks, applied. Regards, Marton
diff --git a/compat/os2threads.h b/compat/os2threads.h index 2177a033ec..eec6f40ae7 100644 --- a/compat/os2threads.h +++ b/compat/os2threads.h @@ -31,11 +31,14 @@ #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) { diff --git a/compat/w32pthreads.h b/compat/w32pthreads.h index 21acfd2ba1..7df33b7da4 100644 --- a/compat/w32pthreads.h +++ b/compat/w32pthreads.h @@ -38,11 +38,13 @@ #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <process.h> +#include <time.h> #include "libavutil/attributes.h" #include "libavutil/common.h" #include "libavutil/internal.h" #include "libavutil/mem.h" +#include "libavutil/time.h" typedef struct pthread_t { void *handle; @@ -156,6 +158,22 @@ 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_sec * 1000LL + abstime->tv_nsec / 1000000; + DWORD t = av_clip64(abs_milli - av_gettime() / 1000, 0, UINT32_MAX); + + if (!SleepConditionVariableSRW(cond, mutex, t, 0)) { + DWORD err = GetLastError(); + if (err == ERROR_TIMEOUT) + return ETIMEDOUT; + else + return EINVAL; + } + return 0; +} + static inline int pthread_cond_signal(pthread_cond_t *cond) { WakeConditionVariable(cond); diff --git a/libavutil/thread.h b/libavutil/thread.h index cc5272d379..65b97ef303 100644 --- a/libavutil/thread.h +++ b/libavutil/thread.h @@ -109,6 +109,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); @@ -124,6 +130,7 @@ static inline int strict_pthread_once(pthread_once_t *once_control, void (*init_ #define pthread_cond_signal strict_pthread_cond_signal #define pthread_cond_broadcast strict_pthread_cond_broadcast #define pthread_cond_wait strict_pthread_cond_wait +#define pthread_cond_timedwait strict_pthread_cond_timedwait #define pthread_once strict_pthread_once #endif