diff --git a/tools/testing/selftests/futex/functional/futex_requeue.c b/tools/testing/selftests/futex/functional/futex_requeue.c index f4b8dc1eccf1..cc31f051765d 100644 --- a/tools/testing/selftests/futex/functional/futex_requeue.c +++ b/tools/testing/selftests/futex/functional/futex_requeue.c @@ -10,21 +10,25 @@ #include #include "futextest.h" +#include "futex_thread.h" #include "kselftest_harness.h" -#define timeout_ns 30000000 -#define WAKE_WAIT_US 10000 +struct waiter_args { + struct __test_metadata *_metadata; + unsigned int n_threads; +}; 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 __test_metadata *_metadata; + struct waiter_args *wargs = arg; + struct timespec to = { }; int res; - to.tv_sec = 0; - to.tv_nsec = timeout_ns; + _metadata = wargs->_metadata; + to.tv_sec = (wargs->n_threads + 1) * WAIT_FOR_THREAD_SECS; res = futex_wait(f1, *f1, &to, 0); if (res) { @@ -32,37 +36,39 @@ void *waiterfn(void *arg) TH_LOG("waiter failed errno %d: %s", errno, strerror(errno)); } - return NULL; + return 0; } TEST(requeue_single) { + struct waiter_args wargs = { ._metadata = _metadata, .n_threads = 1 }; + 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, &wargs), 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 waiter_args wargs = { ._metadata = _metadata, .n_threads = 10 }; + 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 +76,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, &wargs), 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