libthr/thr_mutex.c: make mutex asserts more useful

Print the file and line number of the caller where the assert fired.
Use _thread_exitf() directly for this.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
Konstantin Belousov committed 2026-10-28 02:56:06 +02:00
1 parent f2d4370fbb
commit 4ab9e73994
1 file changed
+30 -22
+30 -22
View File
@@ -131,41 +131,50 @@ mutex_init_link(struct pthread_mutex *m __unused)
#endif
}
static void
mutex_assert_is_owned(struct pthread_mutex *m __unused)
{
#if defined(_PTHREADS_INVARIANTS)
if (__predict_false(m->m_qe.tqe_prev == NULL))
PANIC("mutex %p own %#x is not on list %p %p",
static void
mutex_assert_is_owned(struct pthread_mutex *m, int line)
{
if (__predict_false(m->m_qe.tqe_prev == NULL)) {
_thread_exitf(__FILE__, line,
"mutex %p own %#x is not on list %p %p",
m, m->m_lock.m_owner, m->m_qe.tqe_prev, m->m_qe.tqe_next);
#endif
}
}
static void
mutex_assert_not_owned(struct pthread *curthread __unused,
struct pthread_mutex *m __unused)
mutex_assert_not_owned(struct pthread_mutex *m, int line)
{
struct pthread *curthread;
#if defined(_PTHREADS_INVARIANTS)
curthread = _get_curthread();
if (__predict_false(m->m_qe.tqe_prev != NULL ||
m->m_qe.tqe_next != NULL))
PANIC("mutex %p own %#x is on list %p %p",
m->m_qe.tqe_next != NULL)) {
_thread_exitf(__FILE__, line,
"mutex %p own %#x is on list %p %p",
m, m->m_lock.m_owner, m->m_qe.tqe_prev, m->m_qe.tqe_next);
}
if (__predict_false(is_robust_mutex(m) &&
(m->m_lock.m_rb_lnk != 0 || m->m_rb_prev != NULL ||
(is_pshared_mutex(m) && curthread->robust_list ==
(uintptr_t)&m->m_lock) ||
(!is_pshared_mutex(m) && curthread->priv_robust_list ==
(uintptr_t)&m->m_lock))))
PANIC(
"mutex %p own %#x is on robust linkage %p %p head %p phead %p",
(uintptr_t)&m->m_lock)))) {
_thread_exitf(__FILE__, line,
"mutex %p own %#x is on robust linkage %p %p head %p phead %p",
m, m->m_lock.m_owner, (void *)m->m_lock.m_rb_lnk,
m->m_rb_prev, (void *)curthread->robust_list,
(void *)curthread->priv_robust_list);
#endif
}
}
#define MUTEX_ASSERT_IS_OWNED(m) mutex_assert_is_owned(m, __LINE__)
#define MUTEX_ASSERT_NOT_OWNED(m) mutex_assert_not_owned(m, __LINE__)
#else
#define MUTEX_ASSERT_IS_OWNED(m) do {} while (0)
#define MUTEX_ASSERT_NOT_OWNED(m) do {} while (0)
#endif
static bool
is_pshared_mutex(struct pthread_mutex *m)
{
@@ -477,8 +486,7 @@ _thr_mutex_destroy(pthread_mutex_t *mutex)
if (m1 != NULL) {
if ((uint32_t)m1->m_lock.m_owner !=
UMUTEX_RB_OWNERDEAD) {
mutex_assert_not_owned(
_get_curthread(), m1);
MUTEX_ASSERT_NOT_OWNED(m1);
}
__thr_pshared_destroy(mutex);
}
@@ -490,7 +498,7 @@ _thr_mutex_destroy(pthread_mutex_t *mutex)
ret = EBUSY;
} else {
*mutex = THR_MUTEX_DESTROYED;
mutex_assert_not_owned(_get_curthread(), m);
MUTEX_ASSERT_NOT_OWNED(m);
__thr_free(m);
ret = 0;
}
@@ -530,7 +538,7 @@ enqueue_mutex(struct pthread *curthread, struct pthread_mutex *m,
/* Add to the list of owned mutexes: */
if (error != EOWNERDEAD)
mutex_assert_not_owned(curthread, m);
MUTEX_ASSERT_NOT_OWNED(m);
qidx = mutex_qidx(m);
TAILQ_INSERT_TAIL(&curthread->mq[qidx], m, m_qe);
if (!is_pshared_mutex(m))
@@ -558,7 +566,7 @@ dequeue_mutex(struct pthread *curthread, struct pthread_mutex *m)
struct pthread_mutex *mp, *mn;
int qidx;
mutex_assert_is_owned(m);
MUTEX_ASSERT_IS_OWNED(m);
qidx = mutex_qidx(m);
if (is_robust_mutex(m)) {
mp = m->m_rb_prev;
@@ -1054,7 +1062,7 @@ _pthread_mutex_setprioceiling(pthread_mutex_t * __restrict mutex,
curthread = _get_curthread();
if (PMUTEX_OWNER_ID(m) == TID(curthread)) {
mutex_assert_is_owned(m);
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] > (u_int)ceiling) ||