Index: thread/thr_init.c =================================================================== RCS file: /home/ncvs/src/lib/libthr/thread/thr_init.c,v retrieving revision 1.46 diff -u -r1.46 thr_init.c --- thread/thr_init.c 9 May 2007 08:39:33 -0000 1.46 +++ thread/thr_init.c 17 Oct 2007 08:40:21 -0000 @@ -103,6 +103,8 @@ size_t _thr_stack_default = THR_STACK_DEFAULT; size_t _thr_stack_initial = THR_STACK_INITIAL; int _thr_page_size; +int _thr_max_spins = 1000; +int _thr_min_spins = 200; int _gc_count; struct umutex _mutex_static_lock = DEFAULT_UMUTEX; struct umutex _cond_static_lock = DEFAULT_UMUTEX; @@ -423,6 +425,7 @@ { size_t len; int mib[2]; + char *spin_env; _thr_umutex_init(&_mutex_static_lock); _thr_umutex_init(&_cond_static_lock); @@ -452,7 +455,9 @@ _thr_guard_default = _thr_page_size; _pthread_attr_default.guardsize_attr = _thr_guard_default; _pthread_attr_default.stacksize_attr = _thr_stack_default; - + spin_env = getenv("LIBPTHREAD_MUTEX_MAXSPIN"); + if (spin_env) + _thr_max_spins = atoi(spin_env); TAILQ_INIT(&_thr_atfork_list); } init_once = 1; Index: thread/thr_mutex.c =================================================================== RCS file: /home/ncvs/src/lib/libthr/thread/thr_mutex.c,v retrieving revision 1.54 diff -u -r1.54 thr_mutex.c --- thread/thr_mutex.c 9 May 2007 08:39:33 -0000 1.54 +++ thread/thr_mutex.c 17 Oct 2007 08:40:21 -0000 @@ -121,6 +121,7 @@ pmutex->m_flags |= MUTEX_FLAGS_PRIVATE; pmutex->m_count = 0; pmutex->m_refcount = 0; + pmutex->m_spins = _thr_min_spins; MUTEX_INIT_LINK(pmutex); switch(attr->m_protocol) { case PTHREAD_PRIO_INHERIT: @@ -271,6 +272,16 @@ return (ret); } + +#define ENQUEUE_MUTEX(curthread, m) \ + m->m_owner = curthread; \ + /* Add to the list of owned mutexes: */ \ + MUTEX_ASSERT_NOT_OWNED(m); \ + if ((m->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0) \ + TAILQ_INSERT_TAIL(&curthread->mutexq, m, m_qe); \ + else \ + TAILQ_INSERT_TAIL(&curthread->pp_mutexq, m, m_qe) + static int mutex_trylock_common(struct pthread *curthread, pthread_mutex_t *mutex) { @@ -282,13 +293,7 @@ m = *mutex; ret = _thr_umutex_trylock(&m->m_lock, id); if (ret == 0) { - m->m_owner = curthread; - /* Add to the list of owned mutexes. */ - MUTEX_ASSERT_NOT_OWNED(m); - if ((m->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0) - TAILQ_INSERT_TAIL(&curthread->mutexq, m, m_qe); - else - TAILQ_INSERT_TAIL(&curthread->pp_mutexq, m, m_qe); + ENQUEUE_MUTEX(curthread, m); } else if (m->m_owner == curthread) { ret = mutex_self_trylock(m); } /* else {} */ @@ -340,22 +345,44 @@ struct pthread_mutex *m; uint32_t id; int ret; + int count; + int temp; id = TID(curthread); m = *mutex; ret = _thr_umutex_trylock2(&m->m_lock, id); if (ret == 0) { - m->m_owner = curthread; - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(m); - if ((m->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0) - TAILQ_INSERT_TAIL(&curthread->mutexq, m, m_qe); - else - TAILQ_INSERT_TAIL(&curthread->pp_mutexq, m, m_qe); + ENQUEUE_MUTEX(curthread, m); } else if (m->m_owner == curthread) { ret = mutex_self_lock(m, abstime); } else { if (abstime == NULL) { + if (!(m->m_lock.m_flags & UMUTEX_PRIO_PROTECT)) { + temp = 0; + count = m->m_spins; + while (m->m_lock.m_owner != UMUTEX_UNOWNED) { + if (temp == count) + break; + temp++; + CPU_SPINWAIT; + } + if (temp != count) { + ret = _thr_umutex_trylock2(&m->m_lock, id); + if (ret == 0) { + ENQUEUE_MUTEX(curthread, m); + m->m_spins -= temp/8; + if (m->m_spins < _thr_min_spins) + m->m_spins = _thr_min_spins; + return (ret); + } + } + m->m_spins += temp/8; + if (m->m_spins > _thr_max_spins) { + m->m_spins -= _thr_max_spins; + if (m->m_spins < _thr_min_spins) + m->m_spins = _thr_min_spins; + } + } ret = __thr_umutex_lock(&m->m_lock); } else if (__predict_false( abstime->tv_sec < 0 || abstime->tv_nsec < 0 || @@ -372,16 +399,8 @@ if (ret == EINTR) ret = ETIMEDOUT; } - if (ret == 0) { - m->m_owner = curthread; - /* Add to the list of owned mutexes: */ - MUTEX_ASSERT_NOT_OWNED(m); - if ((m->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0) - TAILQ_INSERT_TAIL(&curthread->mutexq, m, m_qe); - else - TAILQ_INSERT_TAIL(&curthread->pp_mutexq, m, - m_qe); - } + if (ret == 0) + ENQUEUE_MUTEX(curthread, m); } return (ret); } Index: thread/thr_private.h =================================================================== RCS file: /home/ncvs/src/lib/libthr/thread/thr_private.h,v retrieving revision 1.78 diff -u -r1.78 thr_private.h --- thread/thr_private.h 7 Aug 2007 04:50:14 -0000 1.78 +++ thread/thr_private.h 17 Oct 2007 08:40:21 -0000 @@ -119,6 +119,7 @@ int m_flags; int m_count; int m_refcount; + int m_spins; /* * Link for all mutexes a thread currently owns. */ @@ -584,6 +585,8 @@ extern size_t _thr_stack_initial __hidden; extern int _thr_page_size __hidden; extern int _thr_adaptive_spin __hidden; +extern int _thr_max_spins __hidden; +extern int _thr_min_spins __hidden; /* Garbage thread count. */ extern int _gc_count __hidden;