summaryrefslogtreecommitdiffstats
path: root/lib/libthr/thread/thr_mutex.c
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2007-01-05 03:29:15 +0000
committerdavidxu <davidxu@FreeBSD.org>2007-01-05 03:29:15 +0000
commit190109deab04ce14f5d3db5e11056710640c573a (patch)
treed773aa06fbfdecd27e487186f03342633c4463b3 /lib/libthr/thread/thr_mutex.c
parentcb1006da55802dfbb9e2afb672ac18c9e308b800 (diff)
downloadFreeBSD-src-190109deab04ce14f5d3db5e11056710640c573a.zip
FreeBSD-src-190109deab04ce14f5d3db5e11056710640c573a.tar.gz
Check if the PP mutex is recursive, if we have already locked it, place the
mutex in right order sorted by priority ceiling.
Diffstat (limited to 'lib/libthr/thread/thr_mutex.c')
-rw-r--r--lib/libthr/thread/thr_mutex.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/lib/libthr/thread/thr_mutex.c b/lib/libthr/thread/thr_mutex.c
index 17e067a..584b65a 100644
--- a/lib/libthr/thread/thr_mutex.c
+++ b/lib/libthr/thread/thr_mutex.c
@@ -685,14 +685,33 @@ int
_pthread_mutex_setprioceiling(pthread_mutex_t *mutex,
int ceiling, int *old_ceiling)
{
- int ret = 0;
+ struct pthread *curthread = _get_curthread();
+ struct pthread_mutex *m, *m1, *m2;
+ int ret;
- if (*mutex == NULL)
- ret = EINVAL;
- else if (((*mutex)->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0)
- ret = EINVAL;
- else
- ret = __thr_umutex_set_ceiling(&(*mutex)->m_lock,
- ceiling, old_ceiling);
- return (ret);
+ m = *mutex;
+ if (m == NULL || (m->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0)
+ return (EINVAL);
+
+ ret = __thr_umutex_set_ceiling(&m->m_lock, ceiling, old_ceiling);
+ if (ret != 0)
+ return (ret);
+
+ if (m->m_owner == curthread) {
+ MUTEX_ASSERT_IS_OWNED(m);
+ m1 = TAILQ_PREV(m, mutex_queue, m_qe);
+ m2 = TAILQ_NEXT(m, m_qe);
+ if ((m1 != NULL && m1->m_lock.m_ceilings[0] > ceiling) ||
+ (m2 != NULL && m2->m_lock.m_ceilings[0] < ceiling)) {
+ TAILQ_REMOVE(&curthread->pp_mutexq, m, m_qe);
+ TAILQ_FOREACH(m2, &curthread->pp_mutexq, m_qe) {
+ if (m2->m_lock.m_ceilings[0] > ceiling) {
+ TAILQ_INSERT_BEFORE(m2, m, m_qe);
+ return (0);
+ }
+ }
+ }
+ TAILQ_INSERT_HEAD(&curthread->pp_mutexq, m, m_qe);
+ }
+ return (0);
}
OpenPOWER on IntegriCloud