[PATCH 6/6] nptl: Test case for bug 34546
Florian Weimer <[email protected]>
| Newsgroups | gmane.comp.lib.glibc.alpha |
|---|---|
| Message-ID | <14aabc1ffe1cbdb7420050a42184f6ada2769b7b.1787168028.git.fweimer@redhat.com> |
Largely auto-generated, using glibc-specific interfaces, and
following (manually-written) sysdeps/pthread/tst-robust12.c.
Assisted-by: LLM
---
nptl/Makefile | 1 +
nptl/tst-mutexpp11.c | 139 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 140 insertions(+)
create mode 100644 nptl/tst-mutexpp11.c
diff --git a/nptl/Makefile b/nptl/Makefile
index 97a0fb7f65..dc802ae58c 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -311,6 +311,7 @@ tests = \
tst-mutexpi10 \
tst-mutexpi11 \
tst-mutexpi12 \
+ tst-mutexpp11 \
tst-once5 \
tst-pthread-affinity-inheritance \
tst-pthread-attr-affinity \
diff --git a/nptl/tst-mutexpp11.c b/nptl/tst-mutexpp11.c
new file mode 100644
index 0000000000..107a66209a
--- /dev/null
+++ b/nptl/tst-mutexpp11.c
@@ -0,0 +1,139 @@
+/* Test that PP mutex timedlock timeout restores thread priority (bug 34546).
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <pthread.h>
+#include <support/check.h>
+#include <support/timespec.h>
+#include <support/xthread.h>
+#include <support/xtime.h>
+
+#include "tst-tpp.h"
+
+static pthread_mutex_t pp_mutex;
+static pthread_barrier_t barrier;
+
+static void *
+blocker_thread (void *ignored)
+{
+ xpthread_mutex_lock (&pp_mutex);
+
+ /* Tell the main thread that the mutex is held. */
+ xpthread_barrier_wait (&barrier);
+
+ /* Wait for the main thread to finish its test. */
+ xpthread_barrier_wait (&barrier);
+
+ xpthread_mutex_unlock (&pp_mutex);
+ return NULL;
+}
+
+/* Used by CHECK_TPP_PRIORITY. */
+static int ret;
+
+static void
+test_timedlock (void)
+{
+ pthread_t thr = xpthread_create (NULL, blocker_thread, NULL);
+ xpthread_barrier_wait (&barrier);
+
+ CHECK_TPP_PRIORITY (4, 4);
+
+ /* Already-expired timeout. */
+ static const struct timespec t = { -1, 0 };
+ TEST_COMPARE (pthread_mutex_timedlock (&pp_mutex, &t), ETIMEDOUT);
+
+ /* The timeout error path must restore the thread priority. */
+ CHECK_TPP_PRIORITY (4, 4);
+
+ xpthread_barrier_wait (&barrier);
+ xpthread_join (thr);
+}
+
+static void
+test_clocklock (void)
+{
+ pthread_t thr = xpthread_create (NULL, blocker_thread, NULL);
+ xpthread_barrier_wait (&barrier);
+
+ CHECK_TPP_PRIORITY (4, 4);
+
+ /* Already-expired timeout, using CLOCK_REALTIME. */
+ static const struct timespec t = { -1, 0 };
+ TEST_COMPARE (pthread_mutex_clocklock (&pp_mutex, CLOCK_REALTIME, &t),
+ ETIMEDOUT);
+
+ CHECK_TPP_PRIORITY (4, 4);
+
+ /* Already-expired timeout, using CLOCK_MONOTONIC. */
+ TEST_COMPARE (pthread_mutex_clocklock (&pp_mutex, CLOCK_MONOTONIC, &t),
+ ETIMEDOUT);
+
+ CHECK_TPP_PRIORITY (4, 4);
+
+ xpthread_barrier_wait (&barrier);
+ xpthread_join (thr);
+}
+
+static void
+test_timedlock_late (void)
+{
+ pthread_t thr = xpthread_create (NULL, blocker_thread, NULL);
+ xpthread_barrier_wait (&barrier);
+
+ CHECK_TPP_PRIORITY (4, 4);
+
+ /* Timeout in the near future: blocks in the kernel before timing out. */
+ struct timespec t;
+ xclock_gettime (CLOCK_REALTIME, &t);
+ t = timespec_add (t, make_timespec (0, 50 * 1000 * 1000));
+ TEST_COMPARE (pthread_mutex_timedlock (&pp_mutex, &t), ETIMEDOUT);
+
+ CHECK_TPP_PRIORITY (4, 4);
+
+ xpthread_barrier_wait (&barrier);
+ xpthread_join (thr);
+}
+
+static int
+do_test (void)
+{
+ init_tpp_test ();
+
+ /* Create the PP mutex. */
+ {
+ pthread_mutexattr_t ma;
+ xpthread_mutexattr_init (&ma);
+ xpthread_mutexattr_setprotocol (&ma, PTHREAD_PRIO_PROTECT);
+ TEST_COMPARE (pthread_mutexattr_setprioceiling (&ma, 6), 0);
+ xpthread_mutex_init (&pp_mutex, &ma);
+ xpthread_mutexattr_destroy (&ma);
+ }
+
+ xpthread_barrier_init (&barrier, NULL, 2);
+ test_timedlock ();
+ test_clocklock ();
+ test_timedlock_late ();
+ xpthread_barrier_destroy (&barrier);
+
+ xpthread_mutex_destroy (&pp_mutex);
+
+ return ret;
+}
+
+#include <support/test-driver.c>
--
2.55.0