1 // SPDX-License-Identifier: GPL-2.0
5 #include <linux/unistd.h>
6 #include <linux/futex.h>
9 #include <sys/syscall.h>
10 #include <sys/types.h>
18 #define NSEC_PER_SEC 1000000000ULL
20 static int run_test(int clockid)
22 int futex_op = FUTEX_WAIT_BITSET;
23 struct timespec timeout, end;
26 if (clockid == CLOCK_REALTIME)
27 futex_op |= FUTEX_CLOCK_REALTIME;
29 clock_gettime(clockid, &timeout);
30 timeout.tv_nsec += NSEC_PER_SEC / 10; // 100ms
31 if (timeout.tv_nsec > NSEC_PER_SEC) {
33 timeout.tv_nsec -= NSEC_PER_SEC;
36 if (syscall(__NR_futex, &val, futex_op, 0,
37 &timeout, 0, FUTEX_BITSET_MATCH_ANY) >= 0) {
38 ksft_test_result_fail("futex didn't return ETIMEDOUT\n");
42 if (errno != ETIMEDOUT) {
43 ksft_test_result_fail("futex didn't return ETIMEDOUT: %s\n",
48 clock_gettime(clockid, &end);
50 if (end.tv_sec < timeout.tv_sec ||
51 (end.tv_sec == timeout.tv_sec && end.tv_nsec < timeout.tv_nsec)) {
52 ksft_test_result_fail("futex slept less than 100ms\n");
57 ksft_test_result_pass("futex with the %d clockid\n", clockid);
62 int main(int argc, char *argv[])
67 struct timespec mtime_now;
73 clock_gettime(CLOCK_MONOTONIC, &mtime_now);
78 len = snprintf(buf, sizeof(buf), "%d %d 0",
79 CLOCK_MONOTONIC, 70 * 24 * 3600);
80 fd = open("/proc/self/timens_offsets", O_WRONLY);
82 return pr_perror("/proc/self/timens_offsets");
84 if (write(fd, buf, len) != len)
85 return pr_perror("/proc/self/timens_offsets");
91 return pr_perror("Unable to fork");
95 ret |= run_test(CLOCK_REALTIME);
96 ret |= run_test(CLOCK_MONOTONIC);
103 if (waitpid(pid, &status, 0) != pid)
104 return pr_perror("Unable to wait the child process");
106 if (WIFEXITED(status))
107 return WEXITSTATUS(status);