Index: lib/libthr/thread/thr_mutex.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/lib/libthr/thread/thr_mutex.c,v retrieving revision 1.54 diff -u -r1.54 thr_mutex.c --- lib/libthr/thread/thr_mutex.c 9 May 2007 08:39:33 -0000 1.54 +++ lib/libthr/thread/thr_mutex.c 28 Oct 2007 15:45:33 -0000 @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include #include "un-namespace.h" @@ -64,6 +66,10 @@ #define MUTEX_ASSERT_NOT_OWNED(m) #endif +/* For adaptive mutexes, how many times to spin doing trylock2 + before entering the kernel to block */ +#define MUTEX_ADAPTIVE_SPINS 200 + /* * Prototypes */ @@ -355,6 +361,23 @@ } else if (m->m_owner == curthread) { ret = mutex_self_lock(m, abstime); } else { + /* 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) { + int count = MUTEX_ADAPTIVE_SPINS; + + while (count--) { + ret = _thr_umutex_trylock2(&m->m_lock, id); + if (ret == 0) + break; + cpu_spinwait(); + } + } + if (ret == 0) + goto done; + if (abstime == NULL) { ret = __thr_umutex_lock(&m->m_lock); } else if (__predict_false( @@ -372,6 +395,7 @@ if (ret == EINTR) ret = ETIMEDOUT; } +done: if (ret == 0) { m->m_owner = curthread; /* Add to the list of owned mutexes: */ @@ -501,6 +525,7 @@ switch (m->m_type) { case PTHREAD_MUTEX_ERRORCHECK: case PTHREAD_MUTEX_NORMAL: + case PTHREAD_MUTEX_ADAPTIVE_NP: ret = EBUSY; break; Index: lib/libkse/thread/thr_mutex.c =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/lib/libkse/thread/thr_mutex.c,v retrieving revision 1.53 diff -u -r1.53 thr_mutex.c --- lib/libkse/thread/thr_mutex.c 9 Oct 2007 13:42:28 -0000 1.53 +++ lib/libkse/thread/thr_mutex.c 27 Oct 2007 20:03:53 -0000 @@ -179,6 +179,7 @@ /* case PTHREAD_MUTEX_DEFAULT: */ case PTHREAD_MUTEX_ERRORCHECK: case PTHREAD_MUTEX_NORMAL: + case PTHREAD_MUTEX_ADAPTIVE_NP: /* Nothing to do here. */ break; @@ -971,6 +972,7 @@ /* case PTHREAD_MUTEX_DEFAULT: */ case PTHREAD_MUTEX_ERRORCHECK: case PTHREAD_MUTEX_NORMAL: + case PTHREAD_MUTEX_ADAPTIVE_NP: ret = EBUSY; break; @@ -1002,6 +1004,7 @@ switch (m->m_type) { /* case PTHREAD_MUTEX_DEFAULT: */ case PTHREAD_MUTEX_ERRORCHECK: + case PTHREAD_MUTEX_ADAPTIVE_NP: /* * POSIX specifies that mutexes should return EDEADLK if a * recursive lock is detected. Index: include/pthread.h =================================================================== RCS file: /zoo/cvsup/FreeBSD-CVS/src/include/pthread.h,v retrieving revision 1.40 diff -u -r1.40 pthread.h --- include/pthread.h 24 Oct 2005 05:53:54 -0000 1.40 +++ include/pthread.h 27 Oct 2007 18:32:34 -0000 @@ -98,6 +98,7 @@ * Static initialization values. */ #define PTHREAD_MUTEX_INITIALIZER NULL +#define PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP NULL #define PTHREAD_COND_INITIALIZER NULL #define PTHREAD_RWLOCK_INITIALIZER NULL @@ -128,6 +129,7 @@ PTHREAD_MUTEX_ERRORCHECK = 1, /* Default POSIX mutex */ PTHREAD_MUTEX_RECURSIVE = 2, /* Recursive mutex */ PTHREAD_MUTEX_NORMAL = 3, /* No error checking */ + PTHREAD_MUTEX_ADAPTIVE_NP = 4, /* Adaptive mutex, spins briefly before blocking on lock */ PTHREAD_MUTEX_TYPE_MAX };