From owner-svn-src-all@FreeBSD.ORG Sat Aug 11 23:17:03 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 88BF2106566B; Sat, 11 Aug 2012 23:17:03 +0000 (UTC) (envelope-from davidxu@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 72B5B8FC0A; Sat, 11 Aug 2012 23:17:03 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q7BNH3Id010412; Sat, 11 Aug 2012 23:17:03 GMT (envelope-from davidxu@svn.freebsd.org) Received: (from davidxu@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q7BNH3TG010406; Sat, 11 Aug 2012 23:17:03 GMT (envelope-from davidxu@svn.freebsd.org) Message-Id: <201208112317.q7BNH3TG010406@svn.freebsd.org> From: David Xu Date: Sat, 11 Aug 2012 23:17:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r239200 - head/lib/libthr/thread X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 11 Aug 2012 23:17:03 -0000 Author: davidxu Date: Sat Aug 11 23:17:02 2012 New Revision: 239200 URL: http://svn.freebsd.org/changeset/base/239200 Log: MFp4: Further decreases unexpected context switches by defering mutex wakeup until internal sleep queue lock is released. Modified: head/lib/libthr/thread/thr_cond.c head/lib/libthr/thread/thr_kern.c head/lib/libthr/thread/thr_mutex.c head/lib/libthr/thread/thr_private.h head/lib/libthr/thread/thr_umtx.h Modified: head/lib/libthr/thread/thr_cond.c ============================================================================== --- head/lib/libthr/thread/thr_cond.c Sat Aug 11 22:39:27 2012 (r239199) +++ head/lib/libthr/thread/thr_cond.c Sat Aug 11 23:17:02 2012 (r239200) @@ -217,6 +217,7 @@ cond_wait_user(struct pthread_cond *cvp, struct sleepqueue *sq; int recurse; int error; + int defered; if (curthread->wchan != NULL) PANIC("thread was already on queue."); @@ -230,13 +231,23 @@ cond_wait_user(struct pthread_cond *cvp, * 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) { + 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); Modified: head/lib/libthr/thread/thr_kern.c ============================================================================== --- head/lib/libthr/thread/thr_kern.c Sat Aug 11 22:39:27 2012 (r239199) +++ head/lib/libthr/thread/thr_kern.c Sat Aug 11 23:17:02 2012 (r239200) @@ -199,13 +199,6 @@ _thr_sleep(struct pthread *curthread, in const struct timespec *abstime) { - curthread->will_sleep = 0; - if (curthread->nwaiter_defer > 0) { - _thr_wake_all(curthread->defer_waiters, - curthread->nwaiter_defer); - curthread->nwaiter_defer = 0; - } - if (curthread->wake_addr->value != 0) return (0); Modified: head/lib/libthr/thread/thr_mutex.c ============================================================================== --- head/lib/libthr/thread/thr_mutex.c Sat Aug 11 22:39:27 2012 (r239199) +++ head/lib/libthr/thread/thr_mutex.c Sat Aug 11 23:17:02 2012 (r239200) @@ -92,7 +92,7 @@ int __pthread_mutex_setyieldloops_np(pth static int mutex_self_trylock(pthread_mutex_t); static int mutex_self_lock(pthread_mutex_t, const struct timespec *abstime); -static int mutex_unlock_common(struct pthread_mutex *, int); +static int mutex_unlock_common(struct pthread_mutex *, int, int *); static int mutex_lock_sleep(struct pthread *, pthread_mutex_t, const struct timespec *); @@ -461,7 +461,7 @@ _pthread_mutex_unlock(pthread_mutex_t *m struct pthread_mutex *mp; mp = *mutex; - return (mutex_unlock_common(mp, 0)); + return (mutex_unlock_common(mp, 0, NULL)); } int @@ -476,7 +476,7 @@ _mutex_cv_lock(struct pthread_mutex *m, } int -_mutex_cv_unlock(struct pthread_mutex *m, int *count) +_mutex_cv_unlock(struct pthread_mutex *m, int *count, int *defer) { /* @@ -484,7 +484,7 @@ _mutex_cv_unlock(struct pthread_mutex *m */ *count = m->m_count; m->m_count = 0; - (void)mutex_unlock_common(m, 1); + (void)mutex_unlock_common(m, 1, defer); return (0); } @@ -629,7 +629,7 @@ mutex_self_lock(struct pthread_mutex *m, } static int -mutex_unlock_common(struct pthread_mutex *m, int cv) +mutex_unlock_common(struct pthread_mutex *m, int cv, int *mtx_defer) { struct pthread *curthread = _get_curthread(); uint32_t id; @@ -657,12 +657,12 @@ mutex_unlock_common(struct pthread_mutex defered = 1; m->m_flags &= ~PMUTEX_FLAG_DEFERED; } else - defered = 0; + defered = 0; DEQUEUE_MUTEX(curthread, m); - _thr_umutex_unlock(&m->m_lock, id); + _thr_umutex_unlock2(&m->m_lock, id, mtx_defer); - if (curthread->will_sleep == 0 && defered) { + if (mtx_defer == NULL && defered) { _thr_wake_all(curthread->defer_waiters, curthread->nwaiter_defer); curthread->nwaiter_defer = 0; Modified: head/lib/libthr/thread/thr_private.h ============================================================================== --- head/lib/libthr/thread/thr_private.h Sat Aug 11 22:39:27 2012 (r239199) +++ head/lib/libthr/thread/thr_private.h Sat Aug 11 23:17:02 2012 (r239200) @@ -727,10 +727,10 @@ extern struct umutex _thr_event_lock __h */ __BEGIN_DECLS int _thr_setthreaded(int) __hidden; -int _mutex_cv_lock(struct pthread_mutex *, int count) __hidden; -int _mutex_cv_unlock(struct pthread_mutex *, int *count) __hidden; -int _mutex_cv_attach(struct pthread_mutex *, int count) __hidden; -int _mutex_cv_detach(struct pthread_mutex *, int *count) __hidden; +int _mutex_cv_lock(struct pthread_mutex *, int) __hidden; +int _mutex_cv_unlock(struct pthread_mutex *, int *, int *) __hidden; +int _mutex_cv_attach(struct pthread_mutex *, int) __hidden; +int _mutex_cv_detach(struct pthread_mutex *, int *) __hidden; int _mutex_owned(struct pthread *, const struct pthread_mutex *) __hidden; int _mutex_reinit(pthread_mutex_t *) __hidden; void _mutex_fork(struct pthread *curthread) __hidden; Modified: head/lib/libthr/thread/thr_umtx.h ============================================================================== --- head/lib/libthr/thread/thr_umtx.h Sat Aug 11 22:39:27 2012 (r239199) +++ head/lib/libthr/thread/thr_umtx.h Sat Aug 11 23:17:02 2012 (r239200) @@ -120,7 +120,7 @@ _thr_umutex_timedlock(struct umutex *mtx } static inline int -_thr_umutex_unlock(struct umutex *mtx, uint32_t id) +_thr_umutex_unlock2(struct umutex *mtx, uint32_t id, int *defer) { uint32_t flags = mtx->m_flags; @@ -132,8 +132,12 @@ _thr_umutex_unlock(struct umutex *mtx, u return (EPERM); } while (__predict_false(!atomic_cmpset_rel_32(&mtx->m_owner, owner, UMUTEX_UNOWNED))); - if ((owner & UMUTEX_CONTESTED)) - (void)_umtx_op_err(mtx, UMTX_OP_MUTEX_WAKE2, flags, 0, 0); + if ((owner & UMUTEX_CONTESTED)) { + if (defer == NULL) + (void)_umtx_op_err(mtx, UMTX_OP_MUTEX_WAKE2, flags, 0, 0); + else + *defer = 1; + } return (0); } if (atomic_cmpset_rel_32(&mtx->m_owner, id, UMUTEX_UNOWNED)) @@ -142,6 +146,12 @@ _thr_umutex_unlock(struct umutex *mtx, u } static inline int +_thr_umutex_unlock(struct umutex *mtx, uint32_t id) +{ + return _thr_umutex_unlock2(mtx, id, NULL); +} + +static inline int _thr_rwlock_tryrdlock(struct urwlock *rwlock, int flags) { int32_t state;