summaryrefslogtreecommitdiffstats
path: root/lib/libthr/thread/thr_cond.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libthr/thread/thr_cond.c')
-rw-r--r--lib/libthr/thread/thr_cond.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/lib/libthr/thread/thr_cond.c b/lib/libthr/thread/thr_cond.c
index a834711..6af15db 100644
--- a/lib/libthr/thread/thr_cond.c
+++ b/lib/libthr/thread/thr_cond.c
@@ -217,6 +217,7 @@ cond_wait_user(struct pthread_cond *cvp, struct pthread_mutex *mp,
struct sleepqueue *sq;
int recurse;
int error;
+ int defered;
if (curthread->wchan != NULL)
PANIC("thread was already on queue.");
@@ -230,13 +231,24 @@ cond_wait_user(struct pthread_cond *cvp, struct pthread_mutex *mp,
* us to check it without locking in pthread_cond_signal().
*/
cvp->__has_user_waiters = 1;
- curthread->will_sleep = 1;
- (void)_mutex_cv_unlock(mp, &recurse);
+ defered = 0;
+ (void)_mutex_cv_unlock(mp, &recurse, &defered);
curthread->mutex_obj = mp;
_sleepq_add(cvp, curthread);
for(;;) {
_thr_clear_wake(curthread);
_sleepq_unlock(cvp);
+ if (defered) {
+ defered = 0;
+ if ((mp->m_lock.m_owner & UMUTEX_CONTESTED) == 0)
+ (void)_umtx_op_err(&mp->m_lock, UMTX_OP_MUTEX_WAKE2,
+ mp->m_lock.m_flags, 0, 0);
+ }
+ if (curthread->nwaiter_defer > 0) {
+ _thr_wake_all(curthread->defer_waiters,
+ curthread->nwaiter_defer);
+ curthread->nwaiter_defer = 0;
+ }
if (cancel) {
_thr_cancel_enter2(curthread, 0);
OpenPOWER on IntegriCloud