diff options
author | davidxu <davidxu@FreeBSD.org> | 2006-12-12 03:08:49 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2006-12-12 03:08:49 +0000 |
commit | fcda4340a4ca0dc2c34e3a1408e25a156a6bcd9e (patch) | |
tree | c2212f261bb0a72bc508e079a5b950a83c8f8989 /lib/libthr | |
parent | 114b7df825529c758df31aa3a412dc9d38456faf (diff) | |
download | FreeBSD-src-fcda4340a4ca0dc2c34e3a1408e25a156a6bcd9e.zip FreeBSD-src-fcda4340a4ca0dc2c34e3a1408e25a156a6bcd9e.tar.gz |
Move checking for c_has_waiters into low level _thr_ucond_signal and
_thr_ucond_broadcast, clear condition variable pointer in cancellation
info after returing from _thr_ucond_wait, since kernel has already
dropped the internal lock, so we don't need to unlock it in cancellation
handler again.
Diffstat (limited to 'lib/libthr')
-rw-r--r-- | lib/libthr/thread/thr_cond.c | 24 | ||||
-rw-r--r-- | lib/libthr/thread/thr_umtx.c | 4 |
2 files changed, 12 insertions, 16 deletions
diff --git a/lib/libthr/thread/thr_cond.c b/lib/libthr/thread/thr_cond.c index 3ea0534..85eecaa 100644 --- a/lib/libthr/thread/thr_cond.c +++ b/lib/libthr/thread/thr_cond.c @@ -124,13 +124,6 @@ _pthread_cond_destroy(pthread_cond_t *cond) else { cv = *cond; THR_UMUTEX_LOCK(curthread, &cv->c_lock); -#if 0 - /* Lock the condition variable structure: */ - if (cv->c_kerncv.c_has_waiters) { - THR_UMUTEX_UNLOCK(curthread, &cv->c_lock); - return (EBUSY); - } -#endif /* * NULL the caller's pointer now that the condition * variable has been destroyed: @@ -143,7 +136,6 @@ _pthread_cond_destroy(pthread_cond_t *cond) * variable structure: */ free(cv); - } /* Return the completion status: */ return (rval); @@ -163,9 +155,10 @@ cond_cancel_handler(void *arg) struct cond_cancel_info *info = (struct cond_cancel_info *)arg; pthread_cond_t cv; - cv = *(info->cond); - if ((cv->c_lock.m_owner & ~UMUTEX_CONTESTED) == TID(curthread)) + if (info->cond != NULL) { + cv = *(info->cond); THR_UMUTEX_UNLOCK(curthread, &cv->c_lock); + } _mutex_cv_lock(info->mutex, info->count); } @@ -209,6 +202,7 @@ cond_wait_common(pthread_cond_t *cond, pthread_mutex_t *mutex, THR_CLEANUP_PUSH(curthread, cond_cancel_handler, &info); _thr_cancel_enter_defer(curthread); ret = _thr_ucond_wait(&cv->c_kerncv, &cv->c_lock, tsp, 1); + info.cond = NULL; _thr_cancel_leave_defer(curthread, ret); THR_CLEANUP_POP(curthread, 0); } else { @@ -275,12 +269,10 @@ cond_signal_common(pthread_cond_t *cond, int broadcast) cv = *cond; THR_UMUTEX_LOCK(curthread, &cv->c_lock); - if (cv->c_kerncv.c_has_waiters) { - if (!broadcast) - ret = _thr_ucond_signal(&cv->c_kerncv); - else - ret = _thr_ucond_broadcast(&cv->c_kerncv); - } + if (!broadcast) + ret = _thr_ucond_signal(&cv->c_kerncv); + else + ret = _thr_ucond_broadcast(&cv->c_kerncv); THR_UMUTEX_UNLOCK(curthread, &cv->c_lock); return (ret); } diff --git a/lib/libthr/thread/thr_umtx.c b/lib/libthr/thread/thr_umtx.c index 8a8c908..9de346e 100644 --- a/lib/libthr/thread/thr_umtx.c +++ b/lib/libthr/thread/thr_umtx.c @@ -131,6 +131,8 @@ _thr_ucond_wait(struct ucond *cv, struct umutex *m, int _thr_ucond_signal(struct ucond *cv) { + if (!cv->c_has_waiters) + return (0); if (_umtx_op(cv, UMTX_OP_CV_SIGNAL, 0, NULL, NULL) == 0) return (0); return (errno); @@ -139,6 +141,8 @@ _thr_ucond_signal(struct ucond *cv) int _thr_ucond_broadcast(struct ucond *cv) { + if (!cv->c_has_waiters) + return (0); if (_umtx_op(cv, UMTX_OP_CV_BROADCAST, 0, NULL, NULL) == 0) return (0); return (errno); |