diff options
author | davidxu <davidxu@FreeBSD.org> | 2007-10-31 01:37:13 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2007-10-31 01:37:13 +0000 |
commit | e199852bb6031e319928eaef8c89defbf5b596ca (patch) | |
tree | cab382d9647870198902b8742ca35690448d3af5 | |
parent | 53b7cf834ce41e3dedf10a3d8c01b957e5cf2907 (diff) | |
download | FreeBSD-src-e199852bb6031e319928eaef8c89defbf5b596ca.zip FreeBSD-src-e199852bb6031e319928eaef8c89defbf5b596ca.tar.gz |
Restore revision 1.55, the kris's adaptive mutex type.
-rw-r--r-- | lib/libthr/thread/thr_mutex.c | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/lib/libthr/thread/thr_mutex.c b/lib/libthr/thread/thr_mutex.c index d743ca9..0b8a8cc 100644 --- a/lib/libthr/thread/thr_mutex.c +++ b/lib/libthr/thread/thr_mutex.c @@ -67,6 +67,12 @@ #endif /* + * For adaptive mutexes, how many times to spin doing trylock2 + * before entering the kernel to block + */ +#define MUTEX_ADAPTIVE_SPINS 200 + +/* * Prototypes */ int __pthread_mutex_init(pthread_mutex_t *mutex, @@ -356,18 +362,35 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *mutex, } else if (m->m_owner == curthread) { ret = mutex_self_lock(m, abstime); } else { - if (_thr_spinloops != 0 && _thr_is_smp && - !(m->m_lock.m_flags & UMUTEX_PRIO_PROTECT)) { - count = _thr_spinloops; - while (count && m->m_lock.m_owner != UMUTEX_UNOWNED) { - count--; + /* + * For adaptive mutexes, spin for a bit in the expectation + * that if the application requests this mutex type then + * the lock is likely to be released quickly and it is + * faster than entering the kernel + */ + if (m->m_type == PTHREAD_MUTEX_ADAPTIVE_NP) { + count = MUTEX_ADAPTIVE_SPINS; + + while (count--) { + ret = _thr_umutex_trylock2(&m->m_lock, id); + if (ret == 0) + break; CPU_SPINWAIT; } - if (count) { - ret = _thr_umutex_trylock2(&m->m_lock, id); - if (ret == 0) { - ENQUEUE_MUTEX(curthread, m); - return (ret); + if (ret == 0) + goto done; + } else { + if (_thr_spinloops != 0 && _thr_is_smp && + !(m->m_lock.m_flags & UMUTEX_PRIO_PROTECT)) { + count = _thr_spinloops; + while (count) { + if (m->m_lock.m_owner == UMUTEX_UNOWNED) { + ret = _thr_umutex_trylock2(&m->m_lock, id); + if (ret == 0) + goto done; + } + CPU_SPINWAIT; + count--; } } } @@ -377,10 +400,8 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *mutex, while (count--) { _sched_yield(); ret = _thr_umutex_trylock2(&m->m_lock, id); - if (ret == 0) { - ENQUEUE_MUTEX(curthread, m); - return (ret); - } + if (ret == 0) + goto done; } } @@ -401,6 +422,7 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *mutex, if (ret == EINTR) ret = ETIMEDOUT; } +done: if (ret == 0) ENQUEUE_MUTEX(curthread, m); } |