Path: blob/master/tools/testing/selftests/futex/functional/futex_requeue.c
29271 views
// SPDX-License-Identifier: GPL-2.0-or-later1/*2* Copyright Collabora Ltd., 20213*4* futex cmp requeue test by André Almeida <[email protected]>5*/67#include <pthread.h>8#include <limits.h>910#include "futextest.h"11#include "../../kselftest_harness.h"1213#define timeout_ns 3000000014#define WAKE_WAIT_US 100001516volatile futex_t *f1;1718void *waiterfn(void *arg)19{20struct timespec to;2122to.tv_sec = 0;23to.tv_nsec = timeout_ns;2425if (futex_wait(f1, *f1, &to, 0))26printf("waiter failed errno %d\n", errno);2728return NULL;29}3031TEST(requeue_single)32{33volatile futex_t _f1 = 0;34volatile futex_t f2 = 0;35pthread_t waiter[10];36int res;3738f1 = &_f1;3940/*41* Requeue a waiter from f1 to f2, and wake f2.42*/43if (pthread_create(&waiter[0], NULL, waiterfn, NULL))44ksft_exit_fail_msg("pthread_create failed\n");4546usleep(WAKE_WAIT_US);4748ksft_print_dbg_msg("Requeuing 1 futex from f1 to f2\n");49res = futex_cmp_requeue(f1, 0, &f2, 0, 1, 0);50if (res != 1)51ksft_test_result_fail("futex_requeue simple returned: %d %s\n",52res ? errno : res,53res ? strerror(errno) : "");5455ksft_print_dbg_msg("Waking 1 futex at f2\n");56res = futex_wake(&f2, 1, 0);57if (res != 1) {58ksft_test_result_fail("futex_requeue simple returned: %d %s\n",59res ? errno : res,60res ? strerror(errno) : "");61} else {62ksft_test_result_pass("futex_requeue simple succeeds\n");63}64}6566TEST(requeue_multiple)67{68volatile futex_t _f1 = 0;69volatile futex_t f2 = 0;70pthread_t waiter[10];71int res, i;7273f1 = &_f1;7475/*76* Create 10 waiters at f1. At futex_requeue, wake 3 and requeue 7.77* At futex_wake, wake INT_MAX (should be exactly 7).78*/79for (i = 0; i < 10; i++) {80if (pthread_create(&waiter[i], NULL, waiterfn, NULL))81ksft_exit_fail_msg("pthread_create failed\n");82}8384usleep(WAKE_WAIT_US);8586ksft_print_dbg_msg("Waking 3 futexes at f1 and requeuing 7 futexes from f1 to f2\n");87res = futex_cmp_requeue(f1, 0, &f2, 3, 7, 0);88if (res != 10) {89ksft_test_result_fail("futex_requeue many returned: %d %s\n",90res ? errno : res,91res ? strerror(errno) : "");92}9394ksft_print_dbg_msg("Waking INT_MAX futexes at f2\n");95res = futex_wake(&f2, INT_MAX, 0);96if (res != 7) {97ksft_test_result_fail("futex_requeue many returned: %d %s\n",98res ? errno : res,99res ? strerror(errno) : "");100} else {101ksft_test_result_pass("futex_requeue many succeeds\n");102}103}104105TEST_HARNESS_MAIN106107108