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
);