~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/timens/clock_nanosleep.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 #define _GNU_SOURCE
  3 #include <sched.h>
  4 
  5 #include <sys/timerfd.h>
  6 #include <sys/syscall.h>
  7 #include <time.h>
  8 #include <unistd.h>
  9 #include <stdlib.h>
 10 #include <stdio.h>
 11 #include <stdint.h>
 12 #include <pthread.h>
 13 #include <signal.h>
 14 #include <string.h>
 15 
 16 #include "log.h"
 17 #include "timens.h"
 18 
 19 void test_sig(int sig)
 20 {
 21         if (sig == SIGUSR2)
 22                 pthread_exit(NULL);
 23 }
 24 
 25 struct thread_args {
 26         struct timespec *now, *rem;
 27         pthread_mutex_t *lock;
 28         int clockid;
 29         int abs;
 30 };
 31 
 32 void *call_nanosleep(void *_args)
 33 {
 34         struct thread_args *args = _args;
 35 
 36         clock_nanosleep(args->clockid, args->abs ? TIMER_ABSTIME : 0, args->now, args->rem);
 37         pthread_mutex_unlock(args->lock);
 38         return NULL;
 39 }
 40 
 41 int run_test(int clockid, int abs)
 42 {
 43         struct timespec now = {}, rem;
 44         struct thread_args args = { .now = &now, .rem = &rem, .clockid = clockid};
 45         struct timespec start;
 46         pthread_mutex_t lock;
 47         pthread_t thread;
 48         int j, ok, ret;
 49 
 50         signal(SIGUSR1, test_sig);
 51         signal(SIGUSR2, test_sig);
 52 
 53         pthread_mutex_init(&lock, NULL);
 54         pthread_mutex_lock(&lock);
 55 
 56         if (clock_gettime(clockid, &start) == -1) {
 57                 if (errno == EINVAL && check_skip(clockid))
 58                         return 0;
 59                 return pr_perror("clock_gettime");
 60         }
 61 
 62 
 63         if (abs) {
 64                 now.tv_sec = start.tv_sec;
 65                 now.tv_nsec = start.tv_nsec;
 66         }
 67 
 68         now.tv_sec += 3600;
 69         args.abs = abs;
 70         args.lock = &lock;
 71         ret = pthread_create(&thread, NULL, call_nanosleep, &args);
 72         if (ret != 0) {
 73                 pr_err("Unable to create a thread: %s", strerror(ret));
 74                 return 1;
 75         }
 76 
 77         /* Wait when the thread will call clock_nanosleep(). */
 78         ok = 0;
 79         for (j = 0; j < 8; j++) {
 80                 /* The maximum timeout is about 5 seconds. */
 81                 usleep(10000 << j);
 82 
 83                 /* Try to interrupt clock_nanosleep(). */
 84                 pthread_kill(thread, SIGUSR1);
 85 
 86                 usleep(10000 << j);
 87                 /* Check whether clock_nanosleep() has been interrupted or not. */
 88                 if (pthread_mutex_trylock(&lock) == 0) {
 89                         /**/
 90                         ok = 1;
 91                         break;
 92                 }
 93         }
 94         if (!ok)
 95                 pthread_kill(thread, SIGUSR2);
 96         pthread_join(thread, NULL);
 97         pthread_mutex_destroy(&lock);
 98 
 99         if (!ok) {
100                 ksft_test_result_pass("clockid: %d abs:%d timeout\n", clockid, abs);
101                 return 1;
102         }
103 
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);
107                 return 1;
108         }
109         ksft_test_result_pass("clockid: %d abs:%d\n", clockid, abs);
110 
111         return 0;
112 }
113 
114 int main(int argc, char *argv[])
115 {
116         int ret, nsfd;
117 
118         nscheck();
119 
120         ksft_set_plan(4);
121 
122         check_supported_timers();
123 
124         if (unshare_timens())
125                 return 1;
126 
127         if (_settime(CLOCK_MONOTONIC, 7 * 24 * 3600))
128                 return 1;
129         if (_settime(CLOCK_BOOTTIME, 9 * 24 * 3600))
130                 return 1;
131 
132         nsfd = open("/proc/self/ns/time_for_children", O_RDONLY);
133         if (nsfd < 0)
134                 return pr_perror("Unable to open timens_for_children");
135 
136         if (setns(nsfd, CLONE_NEWTIME))
137                 return pr_perror("Unable to set timens");
138 
139         ret = 0;
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);
144 
145         if (ret)
146                 ksft_exit_fail();
147         ksft_exit_pass();
148         return ret;
149 }
150 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php