]> Git Repo - linux.git/blob - tools/testing/selftests/futex/functional/futex_wait.c
scsi: zfcp: Trace when request remove fails after qdio send fails
[linux.git] / tools / testing / selftests / futex / functional / futex_wait.c
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 <sys/shm.h>
10 #include <sys/mman.h>
11 #include <fcntl.h>
12 #include "logging.h"
13 #include "futextest.h"
14
15 #define TEST_NAME "futex-wait"
16 #define timeout_ns  30000000
17 #define WAKE_WAIT_US 10000
18 #define SHM_PATH "futex_shm_file"
19
20 void *futex;
21
22 void usage(char *prog)
23 {
24         printf("Usage: %s\n", prog);
25         printf("  -c    Use color\n");
26         printf("  -h    Display this help message\n");
27         printf("  -v L  Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n",
28                VQUIET, VCRITICAL, VINFO);
29 }
30
31 static void *waiterfn(void *arg)
32 {
33         struct timespec to;
34         unsigned int flags = 0;
35
36         if (arg)
37                 flags = *((unsigned int *) arg);
38
39         to.tv_sec = 0;
40         to.tv_nsec = timeout_ns;
41
42         if (futex_wait(futex, 0, &to, flags))
43                 printf("waiter failed errno %d\n", errno);
44
45         return NULL;
46 }
47
48 int main(int argc, char *argv[])
49 {
50         int res, ret = RET_PASS, fd, c, shm_id;
51         u_int32_t f_private = 0, *shared_data;
52         unsigned int flags = FUTEX_PRIVATE_FLAG;
53         pthread_t waiter;
54         void *shm;
55
56         futex = &f_private;
57
58         while ((c = getopt(argc, argv, "cht:v:")) != -1) {
59                 switch (c) {
60                 case 'c':
61                         log_color(1);
62                         break;
63                 case 'h':
64                         usage(basename(argv[0]));
65                         exit(0);
66                 case 'v':
67                         log_verbosity(atoi(optarg));
68                         break;
69                 default:
70                         usage(basename(argv[0]));
71                         exit(1);
72                 }
73         }
74
75         ksft_print_header();
76         ksft_set_plan(3);
77         ksft_print_msg("%s: Test futex_wait\n", basename(argv[0]));
78
79         /* Testing a private futex */
80         info("Calling private futex_wait on futex: %p\n", futex);
81         if (pthread_create(&waiter, NULL, waiterfn, (void *) &flags))
82                 error("pthread_create failed\n", errno);
83
84         usleep(WAKE_WAIT_US);
85
86         info("Calling private futex_wake on futex: %p\n", futex);
87         res = futex_wake(futex, 1, FUTEX_PRIVATE_FLAG);
88         if (res != 1) {
89                 ksft_test_result_fail("futex_wake private returned: %d %s\n",
90                                       errno, strerror(errno));
91                 ret = RET_FAIL;
92         } else {
93                 ksft_test_result_pass("futex_wake private succeeds\n");
94         }
95
96         /* Testing an anon page shared memory */
97         shm_id = shmget(IPC_PRIVATE, 4096, IPC_CREAT | 0666);
98         if (shm_id < 0) {
99                 perror("shmget");
100                 exit(1);
101         }
102
103         shared_data = shmat(shm_id, NULL, 0);
104
105         *shared_data = 0;
106         futex = shared_data;
107
108         info("Calling shared (page anon) futex_wait on futex: %p\n", futex);
109         if (pthread_create(&waiter, NULL, waiterfn, NULL))
110                 error("pthread_create failed\n", errno);
111
112         usleep(WAKE_WAIT_US);
113
114         info("Calling shared (page anon) futex_wake on futex: %p\n", futex);
115         res = futex_wake(futex, 1, 0);
116         if (res != 1) {
117                 ksft_test_result_fail("futex_wake shared (page anon) returned: %d %s\n",
118                                       errno, strerror(errno));
119                 ret = RET_FAIL;
120         } else {
121                 ksft_test_result_pass("futex_wake shared (page anon) succeeds\n");
122         }
123
124
125         /* Testing a file backed shared memory */
126         fd = open(SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
127         if (fd < 0) {
128                 perror("open");
129                 exit(1);
130         }
131
132         if (ftruncate(fd, sizeof(f_private))) {
133                 perror("ftruncate");
134                 exit(1);
135         }
136
137         shm = mmap(NULL, sizeof(f_private), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
138         if (shm == MAP_FAILED) {
139                 perror("mmap");
140                 exit(1);
141         }
142
143         memcpy(shm, &f_private, sizeof(f_private));
144
145         futex = shm;
146
147         info("Calling shared (file backed) futex_wait on futex: %p\n", futex);
148         if (pthread_create(&waiter, NULL, waiterfn, NULL))
149                 error("pthread_create failed\n", errno);
150
151         usleep(WAKE_WAIT_US);
152
153         info("Calling shared (file backed) futex_wake on futex: %p\n", futex);
154         res = futex_wake(shm, 1, 0);
155         if (res != 1) {
156                 ksft_test_result_fail("futex_wake shared (file backed) returned: %d %s\n",
157                                       errno, strerror(errno));
158                 ret = RET_FAIL;
159         } else {
160                 ksft_test_result_pass("futex_wake shared (file backed) succeeds\n");
161         }
162
163         /* Freeing resources */
164         shmdt(shared_data);
165         munmap(shm, sizeof(f_private));
166         remove(SHM_PATH);
167         close(fd);
168
169         ksft_print_cnts();
170         return ret;
171 }
This page took 0.042963 seconds and 4 git commands to generate.