Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright Collabora Ltd., 2021
4 *
5 * futex cmp requeue test by André Almeida <andrealmeid@collabora.com>
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
17volatile futex_t *f1;
18
19void *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
32TEST(requeue_single)
33{
34 volatile futex_t _f1 = 0;
35 volatile futex_t f2 = 0;
36 pthread_t waiter[10];
37
38 f1 = &_f1;
39
40 /*
41 * Requeue a waiter from f1 to f2, and wake f2.
42 */
43 ASSERT_EQ(0, pthread_create(&waiter[0], NULL, waiterfn, NULL));
44
45 usleep(WAKE_WAIT_US);
46
47 EXPECT_EQ(1, futex_cmp_requeue(f1, 0, &f2, 0, 1, 0));
48 EXPECT_EQ(1, futex_wake(&f2, 1, 0));
49}
50
51TEST(requeue_multiple)
52{
53 volatile futex_t _f1 = 0;
54 volatile futex_t f2 = 0;
55 pthread_t waiter[10];
56 int i;
57
58 f1 = &_f1;
59
60 /*
61 * Create 10 waiters at f1. At futex_requeue, wake 3 and requeue 7.
62 * At futex_wake, wake INT_MAX (should be exactly 7).
63 */
64 for (i = 0; i < 10; i++)
65 ASSERT_EQ(0, pthread_create(&waiter[i], NULL, waiterfn, NULL));
66
67 usleep(WAKE_WAIT_US);
68
69 EXPECT_EQ(10, futex_cmp_requeue(f1, 0, &f2, 3, 7, 0));
70 EXPECT_EQ(7, futex_wake(&f2, INT_MAX, 0));
71}
72
73TEST_HARNESS_MAIN