1 // SPDX-License-Identifier: GPL-2.0
5 #include <sys/timerfd.h>
6 #include <sys/syscall.h>
19 void test_sig(int sig
)
26 struct timespec
*now
, *rem
;
27 pthread_mutex_t
*lock
;
32 void *call_nanosleep(void *_args
)
34 struct thread_args
*args
= _args
;
36 clock_nanosleep(args
->clockid
, args
->abs
? TIMER_ABSTIME
: 0, args
->now
, args
->rem
);
37 pthread_mutex_unlock(args
->lock
);
41 int run_test(int clockid
, int abs
)
43 struct timespec now
= {}, rem
;
44 struct thread_args args
= { .now
= &now
, .rem
= &rem
, .clockid
= clockid
};
45 struct timespec start
;
50 signal(SIGUSR1
, test_sig
);
51 signal(SIGUSR2
, test_sig
);
53 pthread_mutex_init(&lock
, NULL
);
54 pthread_mutex_lock(&lock
);
56 if (clock_gettime(clockid
, &start
) == -1) {
57 if (errno
== EINVAL
&& check_skip(clockid
))
59 return pr_perror("clock_gettime");
64 now
.tv_sec
= start
.tv_sec
;
65 now
.tv_nsec
= start
.tv_nsec
;
71 ret
= pthread_create(&thread
, NULL
, call_nanosleep
, &args
);
73 pr_err("Unable to create a thread: %s", strerror(ret
));
77 /* Wait when the thread will call clock_nanosleep(). */
79 for (j
= 0; j
< 8; j
++) {
80 /* The maximum timeout is about 5 seconds. */
83 /* Try to interrupt clock_nanosleep(). */
84 pthread_kill(thread
, SIGUSR1
);
87 /* Check whether clock_nanosleep() has been interrupted or not. */
88 if (pthread_mutex_trylock(&lock
) == 0) {
95 pthread_kill(thread
, SIGUSR2
);
96 pthread_join(thread
, NULL
);
97 pthread_mutex_destroy(&lock
);
100 ksft_test_result_pass("clockid: %d abs:%d timeout\n", clockid
, abs
);
104 if (rem
.tv_sec
< 3300 || rem
.tv_sec
> 3900) {
105 pr_fail("clockid: %d abs: %d remain: %ld\n",
106 clockid
, abs
, rem
.tv_sec
);
109 ksft_test_result_pass("clockid: %d abs:%d\n", clockid
, abs
);
114 int main(int argc
, char *argv
[])
122 check_supported_timers();
124 if (unshare_timens())
127 if (_settime(CLOCK_MONOTONIC
, 7 * 24 * 3600))
129 if (_settime(CLOCK_BOOTTIME
, 9 * 24 * 3600))
132 nsfd
= open("/proc/self/ns/time_for_children", O_RDONLY
);
134 return pr_perror("Unable to open timens_for_children");
136 if (setns(nsfd
, CLONE_NEWTIME
))
137 return pr_perror("Unable to set timens");
140 ret
|= run_test(CLOCK_MONOTONIC
, 0);
141 ret
|= run_test(CLOCK_MONOTONIC
, 1);
142 ret
|= run_test(CLOCK_BOOTTIME_ALARM
, 0);
143 ret
|= run_test(CLOCK_BOOTTIME_ALARM
, 1);