diff options
author | davidxu <davidxu@FreeBSD.org> | 2007-01-05 03:29:15 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2007-01-05 03:29:15 +0000 |
commit | 190109deab04ce14f5d3db5e11056710640c573a (patch) | |
tree | d773aa06fbfdecd27e487186f03342633c4463b3 /lib/libthr | |
parent | cb1006da55802dfbb9e2afb672ac18c9e308b800 (diff) | |
download | FreeBSD-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')
-rw-r--r-- | lib/libthr/thread/thr_mutex.c | 37 |
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); } |