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.
This commit is contained in:
davidxu 2007-12-14 06:25:57 +00:00
parent 1e3188021c
commit 5340a5f502
4 changed files with 120 additions and 31 deletions

View File

@ -49,6 +49,10 @@ int pthread_mutexattr_setkind_np(pthread_mutexattr_t *, int);
void pthread_resume_all_np(void);
int pthread_resume_np(pthread_t);
void pthread_set_name_np(pthread_t, const char *);
int pthread_mutex_getspinloops_np(pthread_mutex_t *mutex, int *count);
int pthread_mutex_setspinloops_np(pthread_mutex_t *mutex, int count);
int pthread_mutex_getyieldloops_np(pthread_mutex_t *mutex, int *count);
int pthread_mutex_setyieldloops_np(pthread_mutex_t *mutex, int count);
int pthread_single_np(void);
void pthread_suspend_all_np(void);
int pthread_suspend_np(pthread_t);

View File

@ -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;

View File

@ -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--) {
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--;
}
}
}
yield_loop:
if (_thr_yieldloops != 0) {
count = _thr_yieldloops;
while (count--) {
_sched_yield();
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)
goto done;
}
CPU_SPINWAIT;
}
yield_loop:
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);
}

View File

@ -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.
*/