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:
parent
1e3188021c
commit
5340a5f502
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user