Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/selftests/futex/functional/futex_requeue.c
29271 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* Copyright Collabora Ltd., 2021
4
*
5
* futex cmp requeue test by André Almeida <[email protected]>
6
*/
7
8
#include <pthread.h>
9
#include <limits.h>
10
11
#include "futextest.h"
12
#include "../../kselftest_harness.h"
13
14
#define timeout_ns 30000000
15
#define WAKE_WAIT_US 10000
16
17
volatile futex_t *f1;
18
19
void *waiterfn(void *arg)
20
{
21
struct timespec to;
22
23
to.tv_sec = 0;
24
to.tv_nsec = timeout_ns;
25
26
if (futex_wait(f1, *f1, &to, 0))
27
printf("waiter failed errno %d\n", errno);
28
29
return NULL;
30
}
31
32
TEST(requeue_single)
33
{
34
volatile futex_t _f1 = 0;
35
volatile futex_t f2 = 0;
36
pthread_t waiter[10];
37
int res;
38
39
f1 = &_f1;
40
41
/*
42
* Requeue a waiter from f1 to f2, and wake f2.
43
*/
44
if (pthread_create(&waiter[0], NULL, waiterfn, NULL))
45
ksft_exit_fail_msg("pthread_create failed\n");
46
47
usleep(WAKE_WAIT_US);
48
49
ksft_print_dbg_msg("Requeuing 1 futex from f1 to f2\n");
50
res = futex_cmp_requeue(f1, 0, &f2, 0, 1, 0);
51
if (res != 1)
52
ksft_test_result_fail("futex_requeue simple returned: %d %s\n",
53
res ? errno : res,
54
res ? strerror(errno) : "");
55
56
ksft_print_dbg_msg("Waking 1 futex at f2\n");
57
res = futex_wake(&f2, 1, 0);
58
if (res != 1) {
59
ksft_test_result_fail("futex_requeue simple returned: %d %s\n",
60
res ? errno : res,
61
res ? strerror(errno) : "");
62
} else {
63
ksft_test_result_pass("futex_requeue simple succeeds\n");
64
}
65
}
66
67
TEST(requeue_multiple)
68
{
69
volatile futex_t _f1 = 0;
70
volatile futex_t f2 = 0;
71
pthread_t waiter[10];
72
int res, i;
73
74
f1 = &_f1;
75
76
/*
77
* Create 10 waiters at f1. At futex_requeue, wake 3 and requeue 7.
78
* At futex_wake, wake INT_MAX (should be exactly 7).
79
*/
80
for (i = 0; i < 10; i++) {
81
if (pthread_create(&waiter[i], NULL, waiterfn, NULL))
82
ksft_exit_fail_msg("pthread_create failed\n");
83
}
84
85
usleep(WAKE_WAIT_US);
86
87
ksft_print_dbg_msg("Waking 3 futexes at f1 and requeuing 7 futexes from f1 to f2\n");
88
res = futex_cmp_requeue(f1, 0, &f2, 3, 7, 0);
89
if (res != 10) {
90
ksft_test_result_fail("futex_requeue many returned: %d %s\n",
91
res ? errno : res,
92
res ? strerror(errno) : "");
93
}
94
95
ksft_print_dbg_msg("Waking INT_MAX futexes at f2\n");
96
res = futex_wake(&f2, INT_MAX, 0);
97
if (res != 7) {
98
ksft_test_result_fail("futex_requeue many returned: %d %s\n",
99
res ? errno : res,
100
res ? strerror(errno) : "");
101
} else {
102
ksft_test_result_pass("futex_requeue many succeeds\n");
103
}
104
}
105
106
TEST_HARNESS_MAIN
107
108