summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2007-12-14 06:25:57 +0000
committerdavidxu <davidxu@FreeBSD.org>2007-12-14 06:25:57 +0000
commit5340a5f502397bf761127ef489a05170d31910f6 (patch)
tree54bf764117e1fe0a7991caefd3f2ad2dc6ab24f1 /lib
parent1e3188021c5ec8a5073b1c85a13b30e3ce73c484 (diff)
downloadFreeBSD-src-5340a5f502397bf761127ef489a05170d31910f6.zip
FreeBSD-src-5340a5f502397bf761127ef489a05170d31910f6.tar.gz
1. Add function pthread_mutex_setspinloops_np to turn a mutex's spin
loop count. 2. Add function pthread_mutex_setyieldloops_np to turn a mutex's yield loop count. 3. Make environment variables PTHREAD_SPINLOOPS and PTHREAD_YIELDLOOPS to be only used for turnning PTHREAD_MUTEX_ADAPTIVE_NP mutex.
Diffstat (limited to 'lib')
-rw-r--r--lib/libthr/pthread.map8
-rw-r--r--lib/libthr/thread/thr_mutex.c133
-rw-r--r--lib/libthr/thread/thr_private.h2
3 files changed, 114 insertions, 29 deletions
diff --git a/lib/libthr/pthread.map b/lib/libthr/pthread.map
index 92be295..123fdd9 100644
--- a/lib/libthr/pthread.map
+++ b/lib/libthr/pthread.map
@@ -84,9 +84,13 @@ global:
pthread_multi_np;
pthread_mutex_destroy;
pthread_mutex_getprioceiling;
+ pthread_mutex_getspinloops_np;
+ pthread_mutex_getyieldloops_np;
pthread_mutex_init;
pthread_mutex_lock;
pthread_mutex_setprioceiling;
+ pthread_mutex_setspinloops_np;
+ pthread_mutex_setyieldloops_np;
pthread_mutex_timedlock;
pthread_mutex_trylock;
pthread_mutex_unlock;
@@ -284,10 +288,14 @@ global:
_pthread_multi_np;
_pthread_mutex_destroy;
_pthread_mutex_getprioceiling;
+ _pthread_mutex_getspinloops_np;
+ _pthread_mutex_getyieldloops_np;
_pthread_mutex_init;
_pthread_mutex_init_calloc_cb;
_pthread_mutex_lock;
_pthread_mutex_setprioceiling;
+ _pthread_mutex_setspinloops_np;
+ _pthread_mutex_setyieldloops_np;
_pthread_mutex_timedlock;
_pthread_mutex_trylock;
_pthread_mutex_unlock;
diff --git a/lib/libthr/thread/thr_mutex.c b/lib/libthr/thread/thr_mutex.c
index 105ac68..3361799 100644
--- a/lib/libthr/thread/thr_mutex.c
+++ b/lib/libthr/thread/thr_mutex.c
@@ -79,6 +79,8 @@ int __pthread_mutex_trylock(pthread_mutex_t *mutex);
int __pthread_mutex_lock(pthread_mutex_t *mutex);
int __pthread_mutex_timedlock(pthread_mutex_t *mutex,
const struct timespec *abstime);
+int __pthread_mutex_setyieldloops_np(pthread_mutex_t *mutex, int count);
+int _pthread_mutex_getyieldloops_np(pthread_mutex_t *mutex, int *count);
static int mutex_self_trylock(pthread_mutex_t);
static int mutex_self_lock(pthread_mutex_t,
@@ -98,6 +100,12 @@ __weak_reference(_pthread_mutex_unlock, pthread_mutex_unlock);
__weak_reference(_pthread_mutex_getprioceiling, pthread_mutex_getprioceiling);
__weak_reference(_pthread_mutex_setprioceiling, pthread_mutex_setprioceiling);
+__weak_reference(__pthread_mutex_setspinloops_np, pthread_mutex_setspinloops_np);
+__weak_reference(_pthread_mutex_getspinloops_np, pthread_mutex_getspinloops_np);
+
+__weak_reference(__pthread_mutex_setyieldloops_np, pthread_mutex_setyieldloops_np);
+__weak_reference(_pthread_mutex_getyieldloops_np, pthread_mutex_getyieldloops_np);
+
static int
mutex_init(pthread_mutex_t *mutex,
const pthread_mutexattr_t *mutex_attr, int private,
@@ -128,6 +136,8 @@ mutex_init(pthread_mutex_t *mutex,
pmutex->m_flags |= MUTEX_FLAGS_PRIVATE;
pmutex->m_count = 0;
pmutex->m_refcount = 0;
+ pmutex->m_spinloops = 0;
+ pmutex->m_yieldloops = 0;
MUTEX_INIT_LINK(pmutex);
switch(attr->m_protocol) {
case PTHREAD_PRIO_INHERIT:
@@ -143,6 +153,13 @@ mutex_init(pthread_mutex_t *mutex,
pmutex->m_lock.m_owner = UMUTEX_UNOWNED;
pmutex->m_lock.m_flags = 0;
}
+
+ if (pmutex->m_type == PTHREAD_MUTEX_ADAPTIVE_NP) {
+ pmutex->m_spinloops =
+ _thr_spinloops ? _thr_spinloops: MUTEX_ADAPTIVE_SPINS;
+ pmutex->m_yieldloops = _thr_yieldloops;
+ }
+
*mutex = pmutex;
return (0);
}
@@ -391,41 +408,23 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *mutex,
if (!_thr_is_smp)
goto yield_loop;
- if (m->m_type == PTHREAD_MUTEX_ADAPTIVE_NP) {
- count = MUTEX_ADAPTIVE_SPINS;
-
- while (count--) {
+ count = m->m_spinloops;
+ while (count--) {
+ if (m->m_lock.m_owner == UMUTEX_UNOWNED) {
ret = _thr_umutex_trylock2(&m->m_lock, id);
if (ret == 0)
- break;
- CPU_SPINWAIT;
- }
- if (ret == 0)
- goto done;
- } else {
- if (_thr_spinloops != 0) {
- 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--;
- }
+ goto done;
}
+ CPU_SPINWAIT;
}
yield_loop:
- if (_thr_yieldloops != 0) {
- count = _thr_yieldloops;
- while (count--) {
- _sched_yield();
- ret = _thr_umutex_trylock2(&m->m_lock, id);
- if (ret == 0)
- goto done;
- }
+ count = m->m_yieldloops;
+ while (count--) {
+ _sched_yield();
+ ret = _thr_umutex_trylock2(&m->m_lock, id);
+ if (ret == 0)
+ goto done;
}
sleep_in_kernel:
@@ -782,3 +781,79 @@ _pthread_mutex_setprioceiling(pthread_mutex_t *mutex,
}
return (0);
}
+
+int
+_pthread_mutex_getspinloops_np(pthread_mutex_t *mutex, int *count)
+{
+ if (*mutex == NULL)
+ return (0);
+ return (*mutex)->m_spinloops;
+}
+
+int
+_pthread_mutex_setspinloops_np(pthread_mutex_t *mutex, int count)
+{
+ struct pthread *curthread = _get_curthread();
+ int ret;
+
+ if (__predict_false(*mutex == NULL)) {
+ ret = init_static_private(curthread, mutex);
+ if (__predict_false(ret))
+ return (ret);
+ }
+ (*mutex)->m_spinloops = count;
+ return (0);
+}
+
+int
+__pthread_mutex_setspinloops_np(pthread_mutex_t *mutex, int count)
+{
+ struct pthread *curthread = _get_curthread();
+ int ret;
+
+ if (__predict_false(*mutex == NULL)) {
+ ret = init_static(curthread, mutex);
+ if (__predict_false(ret))
+ return (ret);
+ }
+ (*mutex)->m_spinloops = count;
+ return (0);
+}
+
+int
+_pthread_mutex_getyieldloops_np(pthread_mutex_t *mutex, int *count)
+{
+ if (*mutex == NULL)
+ return (0);
+ return (*mutex)->m_yieldloops;
+}
+
+int
+_pthread_mutex_setyieldloops_np(pthread_mutex_t *mutex, int count)
+{
+ struct pthread *curthread = _get_curthread();
+ int ret;
+
+ if (__predict_false(*mutex == NULL)) {
+ ret = init_static_private(curthread, mutex);
+ if (__predict_false(ret))
+ return (ret);
+ }
+ (*mutex)->m_yieldloops = count;
+ return (0);
+}
+
+int
+__pthread_mutex_setyieldloops_np(pthread_mutex_t *mutex, int count)
+{
+ struct pthread *curthread = _get_curthread();
+ int ret;
+
+ if (__predict_false(*mutex == NULL)) {
+ ret = init_static(curthread, mutex);
+ if (__predict_false(ret))
+ return (ret);
+ }
+ (*mutex)->m_yieldloops = count;
+ return (0);
+}
diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h
index abde74f..387f0de 100644
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -119,6 +119,8 @@ struct pthread_mutex {
int m_flags;
int m_count;
int m_refcount;
+ int m_spinloops;
+ int m_yieldloops;
/*
* Link for all mutexes a thread currently owns.
*/
OpenPOWER on IntegriCloud