[tip: locking/futex] selftests/futex: Use thread synchronization helpers instead of usleep()
From: tip-bot2 for Yuwen Chen
Date: Sun Jul 05 2026 - 15:55:04 EST
The following commit has been merged into the locking/futex branch of tip:
Commit-ID: 157a9b22ff769e1a657aec6210df3ea896600eec
Gitweb: https://git.kernel.org/tip/157a9b22ff769e1a657aec6210df3ea896600eec
Author: Yuwen Chen <ywen.chen@xxxxxxxxxxx>
AuthorDate: Mon, 18 May 2026 10:16:54 +08:00
Committer: Thomas Gleixner <tglx@xxxxxxxxxx>
CommitterDate: Sun, 05 Jul 2026 21:49:18 +02:00
selftests/futex: Use thread synchronization helpers instead of usleep()
This test uses usleep() to delay the main thread after creating the test
thread[s] under the assumption that they already are blocked on the futex
when the main thread continues.
That "works" on otherwise idle systems, but fails under load resulting in
failed selftests because the requeue operation starts before the waiters
reached the kernel.
Replace the usleep() waits by the new thread synchronization helpers to cure that.
[ tglx: Adapted to test harness changes, fixed coding style, sanitized the
timeout handling and rewrote change log.
Co-developed-by: Edward Liaw <edliaw@xxxxxxxxxx>
Signed-off-by: Yuwen Chen <ywen.chen@xxxxxxxxxxx>
Signed-off-by: Edward Liaw <edliaw@xxxxxxxxxx>
Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxx>
Link: https://patch.msgid.link/tencent_76B9DE9C9FE5C57F6D74B5149970DF8CCF0A@xxxxxx
---
tools/testing/selftests/futex/functional/futex_requeue.c | 38 +++----
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/tools/testing/selftests/futex/functional/futex_requeue.c b/tools/testing/selftests/futex/functional/futex_requeue.c
index f4b8dc1..22e7046 100644
--- a/tools/testing/selftests/futex/functional/futex_requeue.c
+++ b/tools/testing/selftests/futex/functional/futex_requeue.c
@@ -10,59 +10,56 @@
#include <string.h>
#include "futextest.h"
+#include "futex_thread.h"
#include "kselftest_harness.h"
-#define timeout_ns 30000000
-#define WAKE_WAIT_US 10000
+#define FUTEX_WAIT_TIMEOUT_SECS 2
volatile futex_t *f1;
-void *waiterfn(void *arg)
+static int waiterfn(void *arg)
{
struct __test_metadata *_metadata = (struct __test_metadata *)arg;
- struct timespec to;
+ struct timespec to = { .tv_sec = FUTEX_WAIT_TIMEOUT_SECS };
int res;
- to.tv_sec = 0;
- to.tv_nsec = timeout_ns;
-
res = futex_wait(f1, *f1, &to, 0);
if (res) {
EXPECT_EQ(res, 0)
TH_LOG("waiter failed errno %d: %s", errno, strerror(errno));
}
- return NULL;
+ return 0;
}
TEST(requeue_single)
{
+ struct futex_thread waiter;
volatile futex_t _f1 = 0;
volatile futex_t f2 = 0;
- pthread_t waiter[10];
f1 = &_f1;
/*
* Requeue a waiter from f1 to f2, and wake f2.
*/
- ASSERT_EQ(pthread_create(&waiter[0], NULL, waiterfn, _metadata), 0)
+ ASSERT_EQ(futex_thread_create(&waiter, waiterfn, _metadata), 0)
TH_LOG("pthread_create failed");
- usleep(WAKE_WAIT_US);
+ ASSERT_EQ(futex_wait_for_thread(&waiter, _metadata), 0)
+ TH_LOG("Wait for thread failed");
EXPECT_EQ(futex_cmp_requeue(f1, 0, &f2, 0, 1, 0), 1);
EXPECT_EQ(futex_wake(&f2, 1, 0), 1);
- pthread_join(waiter[0], NULL);
+ EXPECT_EQ(futex_thread_destroy(&waiter), 0);
}
TEST(requeue_multiple)
{
+ struct futex_thread waiter[10];
volatile futex_t _f1 = 0;
volatile futex_t f2 = 0;
- pthread_t waiter[10];
- int i;
f1 = &_f1;
@@ -70,18 +67,21 @@ TEST(requeue_multiple)
* Create 10 waiters at f1. At futex_requeue, wake 3 and requeue 7.
* At futex_wake, wake INT_MAX (should be exactly 7).
*/
- for (i = 0; i < 10; i++) {
- ASSERT_EQ(pthread_create(&waiter[i], NULL, waiterfn, _metadata), 0)
+ for (int i = 0; i < 10; i++) {
+ ASSERT_EQ(futex_thread_create(&waiter[i], waiterfn, _metadata), 0)
TH_LOG("pthread_create failed for waiter %d", i);
}
- usleep(WAKE_WAIT_US);
+ for (int i = 0; i < 10; i++) {
+ ASSERT_EQ(futex_wait_for_thread(&waiter[i], _metadata), 0)
+ TH_LOG("Wait for waiter thread %d failed", i);
+ }
EXPECT_EQ(futex_cmp_requeue(f1, 0, &f2, 3, 7, 0), 10);
EXPECT_EQ(futex_wake(&f2, INT_MAX, 0), 7);
- for (i = 0; i < 10; i++)
- pthread_join(waiter[i], NULL);
+ for (int i = 0; i < 10; i++)
+ EXPECT_EQ(futex_thread_destroy(&waiter[i]), 0);
}
TEST_HARNESS_MAIN