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);
|
void pthread_resume_all_np(void);
|
||||||
int pthread_resume_np(pthread_t);
|
int pthread_resume_np(pthread_t);
|
||||||
void pthread_set_name_np(pthread_t, const char *);
|
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);
|
int pthread_single_np(void);
|
||||||
void pthread_suspend_all_np(void);
|
void pthread_suspend_all_np(void);
|
||||||
int pthread_suspend_np(pthread_t);
|
int pthread_suspend_np(pthread_t);
|
||||||
|
@ -84,9 +84,13 @@ global:
|
|||||||
pthread_multi_np;
|
pthread_multi_np;
|
||||||
pthread_mutex_destroy;
|
pthread_mutex_destroy;
|
||||||
pthread_mutex_getprioceiling;
|
pthread_mutex_getprioceiling;
|
||||||
|
pthread_mutex_getspinloops_np;
|
||||||
|
pthread_mutex_getyieldloops_np;
|
||||||
pthread_mutex_init;
|
pthread_mutex_init;
|
||||||
pthread_mutex_lock;
|
pthread_mutex_lock;
|
||||||
pthread_mutex_setprioceiling;
|
pthread_mutex_setprioceiling;
|
||||||
|
pthread_mutex_setspinloops_np;
|
||||||
|
pthread_mutex_setyieldloops_np;
|
||||||
pthread_mutex_timedlock;
|
pthread_mutex_timedlock;
|
||||||
pthread_mutex_trylock;
|
pthread_mutex_trylock;
|
||||||
pthread_mutex_unlock;
|
pthread_mutex_unlock;
|
||||||
@ -284,10 +288,14 @@ global:
|
|||||||
_pthread_multi_np;
|
_pthread_multi_np;
|
||||||
_pthread_mutex_destroy;
|
_pthread_mutex_destroy;
|
||||||
_pthread_mutex_getprioceiling;
|
_pthread_mutex_getprioceiling;
|
||||||
|
_pthread_mutex_getspinloops_np;
|
||||||
|
_pthread_mutex_getyieldloops_np;
|
||||||
_pthread_mutex_init;
|
_pthread_mutex_init;
|
||||||
_pthread_mutex_init_calloc_cb;
|
_pthread_mutex_init_calloc_cb;
|
||||||
_pthread_mutex_lock;
|
_pthread_mutex_lock;
|
||||||
_pthread_mutex_setprioceiling;
|
_pthread_mutex_setprioceiling;
|
||||||
|
_pthread_mutex_setspinloops_np;
|
||||||
|
_pthread_mutex_setyieldloops_np;
|
||||||
_pthread_mutex_timedlock;
|
_pthread_mutex_timedlock;
|
||||||
_pthread_mutex_trylock;
|
_pthread_mutex_trylock;
|
||||||
_pthread_mutex_unlock;
|
_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_lock(pthread_mutex_t *mutex);
|
||||||
int __pthread_mutex_timedlock(pthread_mutex_t *mutex,
|
int __pthread_mutex_timedlock(pthread_mutex_t *mutex,
|
||||||
const struct timespec *abstime);
|
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_trylock(pthread_mutex_t);
|
||||||
static int mutex_self_lock(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_getprioceiling, pthread_mutex_getprioceiling);
|
||||||
__weak_reference(_pthread_mutex_setprioceiling, pthread_mutex_setprioceiling);
|
__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
|
static int
|
||||||
mutex_init(pthread_mutex_t *mutex,
|
mutex_init(pthread_mutex_t *mutex,
|
||||||
const pthread_mutexattr_t *mutex_attr, int private,
|
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_flags |= MUTEX_FLAGS_PRIVATE;
|
||||||
pmutex->m_count = 0;
|
pmutex->m_count = 0;
|
||||||
pmutex->m_refcount = 0;
|
pmutex->m_refcount = 0;
|
||||||
|
pmutex->m_spinloops = 0;
|
||||||
|
pmutex->m_yieldloops = 0;
|
||||||
MUTEX_INIT_LINK(pmutex);
|
MUTEX_INIT_LINK(pmutex);
|
||||||
switch(attr->m_protocol) {
|
switch(attr->m_protocol) {
|
||||||
case PTHREAD_PRIO_INHERIT:
|
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_owner = UMUTEX_UNOWNED;
|
||||||
pmutex->m_lock.m_flags = 0;
|
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;
|
*mutex = pmutex;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -391,41 +408,23 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *mutex,
|
|||||||
if (!_thr_is_smp)
|
if (!_thr_is_smp)
|
||||||
goto yield_loop;
|
goto yield_loop;
|
||||||
|
|
||||||
if (m->m_type == PTHREAD_MUTEX_ADAPTIVE_NP) {
|
count = m->m_spinloops;
|
||||||
count = MUTEX_ADAPTIVE_SPINS;
|
while (count--) {
|
||||||
|
if (m->m_lock.m_owner == UMUTEX_UNOWNED) {
|
||||||
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();
|
|
||||||
ret = _thr_umutex_trylock2(&m->m_lock, id);
|
ret = _thr_umutex_trylock2(&m->m_lock, id);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
goto done;
|
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:
|
sleep_in_kernel:
|
||||||
@ -782,3 +781,79 @@ _pthread_mutex_setprioceiling(pthread_mutex_t *mutex,
|
|||||||
}
|
}
|
||||||
return (0);
|
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_flags;
|
||||||
int m_count;
|
int m_count;
|
||||||
int m_refcount;
|
int m_refcount;
|
||||||
|
int m_spinloops;
|
||||||
|
int m_yieldloops;
|
||||||
/*
|
/*
|
||||||
* Link for all mutexes a thread currently owns.
|
* Link for all mutexes a thread currently owns.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user