diff options
author | KO Myung-Hun <komh78@gmail.com> | 2016-02-14 18:20:33 +0300 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2016-02-14 21:17:36 +0300 |
commit | 22a4046d66f7f60eb771c5fe7d2a9b42989d420c (patch) | |
tree | cc368985d29dca4c8af0db29da5512031b03331a /compat/os2threads.h | |
parent | b65ea6ab449012b45fdfe0c006217e8bc5c59a94 (diff) |
compat/os2threads: Improve pthread_cond_xxx() functions
1. Manipulate waiting count in pthread_cond_wait()
2. Use builtin atomic functions to manipulate waiting count
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'compat/os2threads.h')
-rw-r--r-- | compat/os2threads.h | 26 |
1 files changed, 15 insertions, 11 deletions
diff --git a/compat/os2threads.h b/compat/os2threads.h index 7c0fe13af3..12cb7b0dab 100644 --- a/compat/os2threads.h +++ b/compat/os2threads.h @@ -32,6 +32,7 @@ #undef __STRICT_ANSI__ /* for _beginthread() */ #include <stdlib.h> +#include <sys/builtin.h> #include <sys/fmutex.h> #include "libavutil/mem.h" @@ -43,8 +44,9 @@ typedef HMTX pthread_mutex_t; typedef void pthread_mutexattr_t; typedef struct { - HEV event_sem; - int wait_count; + HEV event_sem; + HEV ack_sem; + volatile unsigned wait_count; } pthread_cond_t; typedef void pthread_condattr_t; @@ -124,6 +126,7 @@ static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex) static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) { DosCreateEventSem(NULL, &cond->event_sem, DCE_POSTONE, FALSE); + DosCreateEventSem(NULL, &cond->ack_sem, DCE_POSTONE, FALSE); cond->wait_count = 0; @@ -133,16 +136,16 @@ static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthrea static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond) { DosCloseEventSem(cond->event_sem); + DosCloseEventSem(cond->ack_sem); return 0; } static av_always_inline int pthread_cond_signal(pthread_cond_t *cond) { - if (cond->wait_count > 0) { + if (!__atomic_cmpxchg32(&cond->wait_count, 0, 0)) { DosPostEventSem(cond->event_sem); - - cond->wait_count--; + DosWaitEventSem(cond->ack_sem, SEM_INDEFINITE_WAIT); } return 0; @@ -150,23 +153,24 @@ static av_always_inline int pthread_cond_signal(pthread_cond_t *cond) static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond) { - while (cond->wait_count > 0) { - DosPostEventSem(cond->event_sem); - - cond->wait_count--; - } + while (!__atomic_cmpxchg32(&cond->wait_count, 0, 0)) + pthread_cond_signal(cond); return 0; } static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { - cond->wait_count++; + __atomic_increment(&cond->wait_count); pthread_mutex_unlock(mutex); DosWaitEventSem(cond->event_sem, SEM_INDEFINITE_WAIT); + __atomic_decrement(&cond->wait_count); + + DosPostEventSem(cond->ack_sem); + pthread_mutex_lock(mutex); return 0; |