git: 4ab9e73994e6 - main - libthr/thr_mutex.c: make mutex asserts more useful
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 28 Oct 2026 01:09:39 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=4ab9e73994e673e518d1b0631f8ce7d1faec6d80
commit 4ab9e73994e673e518d1b0631f8ce7d1faec6d80
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-10-27 13:05:59 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-10-28 00:56:06 +0000
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
---
lib/libthr/thread/thr_mutex.c | 50 +++++++++++++++++++++++++------------------
1 file changed, 29 insertions(+), 21 deletions(-)
diff --git a/lib/libthr/thread/thr_mutex.c b/lib/libthr/thread/thr_mutex.c
index 9c0939aa6080..58c79c973a9b 100644
--- a/lib/libthr/thread/thr_mutex.c
+++ b/lib/libthr/thread/thr_mutex.c
@@ -131,41 +131,50 @@ mutex_init_link(struct pthread_mutex *m __unused)
#endif
}
+#if defined(_PTHREADS_INVARIANTS)
static void
-mutex_assert_is_owned(struct pthread_mutex *m __unused)
+mutex_assert_is_owned(struct pthread_mutex *m, int line)
{
-
-#if defined(_PTHREADS_INVARIANTS)
- if (__predict_false(m->m_qe.tqe_prev == NULL))
- PANIC("mutex %p own %#x is not on list %p %p",
+ 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) ||