diff mbox series

[FFmpeg-devel,PATCHv2] avutil/thread: Add pthread_cond_timedwait function

Message ID 20200120001430.28857-1-cus@passwd.hu
State Accepted
Headers show
Series [FFmpeg-devel,PATCHv2] avutil/thread: Add pthread_cond_timedwait function | expand

Checks

Context Check Description
andriy/ffmpeg-patchwork success Make fate finished

Commit Message

Marton Balint Jan. 20, 2020, 12:14 a.m. UTC
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(+)

Comments

Matt Oliver Jan. 20, 2020, 1:50 a.m. UTC | #1
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
Marton Balint Jan. 21, 2020, 9:53 p.m. UTC | #2
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 mbox series

Patch

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