1 /* Tests for POSIX timer implementation.
2 Copyright (C) 2004-2024 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public License as
7 published by the Free Software Foundation; either version 2.1 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, see <https://www.gnu.org/licenses/>. */
26 #if _POSIX_THREADS && defined SA_SIGINFO
30 # define TEST_CLOCK CLOCK_REALTIME
33 pthread_mutex_t lock
= PTHREAD_MUTEX_INITIALIZER
;
34 pthread_cond_t cond
= PTHREAD_COND_INITIALIZER
;
36 timer_t timer_none
, timer_sig1
, timer_sig2
, timer_thr1
, timer_thr2
;
38 int thr1_cnt
, thr1_err
;
39 union sigval thr1_sigval
;
40 struct timespec thr1_ts
;
43 thr1 (union sigval sigval
)
45 pthread_mutex_lock (&lock
);
46 thr1_err
= clock_gettime (TEST_CLOCK
, &thr1_ts
);
49 struct itimerspec it
= { };
50 thr1_err
|= timer_settime (timer_thr1
, 0, &it
, NULL
);
54 pthread_cond_signal (&cond
);
55 pthread_mutex_unlock (&lock
);
58 int thr2_cnt
, thr2_err
;
59 union sigval thr2_sigval
;
60 size_t thr2_guardsize
;
61 struct timespec thr2_ts
;
64 thr2 (union sigval sigval
)
68 size_t guardsize
= -1;
69 int ret
= pthread_getattr_np (pthread_self (), &nattr
);
73 printf ("*** pthread_getattr_np failed: %m\n");
78 ret
= pthread_attr_getguardsize (&nattr
, &guardsize
);
82 printf ("*** pthread_attr_getguardsize failed: %m\n");
85 if (pthread_attr_destroy (&nattr
) != 0)
87 puts ("*** pthread_attr_destroy failed");
91 pthread_mutex_lock (&lock
);
92 thr2_err
= clock_gettime (TEST_CLOCK
, &thr2_ts
) | err
;
95 struct itimerspec it
= { };
96 thr2_err
|= timer_settime (timer_thr2
, 0, &it
, NULL
);
100 thr2_guardsize
= guardsize
;
101 pthread_cond_signal (&cond
);
102 pthread_mutex_unlock (&lock
);
105 volatile int sig1_cnt
, sig1_err
;
106 volatile union sigval sig1_sigval
;
107 struct timespec sig1_ts
;
110 sig1_handler (int sig
, siginfo_t
*info
, void *ctx
)
113 if (sig
!= SIGRTMIN
) err
|= 1 << 0;
114 if (info
->si_signo
!= SIGRTMIN
) err
|= 1 << 1;
115 if (info
->si_code
!= SI_TIMER
) err
|= 1 << 2;
116 if (clock_gettime (TEST_CLOCK
, &sig1_ts
) != 0)
120 struct itimerspec it
= { };
121 if (timer_settime (timer_sig1
, 0, &it
, NULL
))
125 sig1_sigval
= info
->si_value
;
129 volatile int sig2_cnt
, sig2_err
;
130 volatile union sigval sig2_sigval
;
131 struct timespec sig2_ts
;
134 sig2_handler (int sig
, siginfo_t
*info
, void *ctx
)
137 if (sig
!= SIGRTMIN
+ 1) err
|= 1 << 0;
138 if (info
->si_signo
!= SIGRTMIN
+ 1) err
|= 1 << 1;
139 if (info
->si_code
!= SI_TIMER
) err
|= 1 << 2;
140 if (clock_gettime (TEST_CLOCK
, &sig2_ts
) != 0)
144 struct itimerspec it
= { };
145 if (timer_settime (timer_sig2
, 0, &it
, NULL
))
149 sig2_sigval
= info
->si_value
;
153 /* Check if end is later or equal to start + nsec. */
155 check_ts (const char *name
, const struct timespec
*start
,
156 const struct timespec
*end
, long msec
)
158 struct timespec ts
= *start
;
160 ts
.tv_sec
+= msec
/ 1000000;
161 ts
.tv_nsec
+= (msec
% 1000000) * 1000;
162 if (ts
.tv_nsec
>= 1000000000)
165 ts
.tv_nsec
-= 1000000000;
167 if (end
->tv_sec
< ts
.tv_sec
168 || (end
->tv_sec
== ts
.tv_sec
&& end
->tv_nsec
< ts
.tv_nsec
))
171 *** timer %s invoked too soon: %ld.%09jd instead of expected %ld.%09jd\n",
172 name
, (long) end
->tv_sec
, (intmax_t) end
->tv_nsec
,
173 (long) ts
.tv_sec
, (intmax_t) ts
.tv_nsec
);
180 #define TEST_FUNCTION do_test ()
186 #ifdef TEST_CLOCK_MISSING
187 const char *missing
= TEST_CLOCK_MISSING (TEST_CLOCK
);
190 printf ("%s missing, skipping test\n", missing
);
196 if (clock_gettime (TEST_CLOCK
, &ts
) != 0)
198 printf ("*** clock_gettime failed: %m\n");
202 printf ("clock_gettime returned timespec = { %ld, %jd }\n",
203 (long) ts
.tv_sec
, (intmax_t) ts
.tv_nsec
);
205 if (clock_getres (TEST_CLOCK
, &ts
) != 0)
207 printf ("*** clock_getres failed: %m\n");
211 printf ("clock_getres returned timespec = { %ld, %jd }\n",
212 (long) ts
.tv_sec
, (intmax_t) ts
.tv_nsec
);
215 memset (&ev
, 0x11, sizeof (ev
));
216 ev
.sigev_notify
= SIGEV_NONE
;
217 if (timer_create (TEST_CLOCK
, &ev
, &timer_none
) != 0)
219 printf ("*** timer_create for timer_none failed: %m\n");
223 struct sigaction sa
= { .sa_sigaction
= sig1_handler
,
224 .sa_flags
= SA_SIGINFO
};
225 sigemptyset (&sa
.sa_mask
);
226 sigaction (SIGRTMIN
, &sa
, NULL
);
227 sa
.sa_sigaction
= sig2_handler
;
228 sigaction (SIGRTMIN
+ 1, &sa
, NULL
);
230 memset (&ev
, 0x22, sizeof (ev
));
231 ev
.sigev_notify
= SIGEV_SIGNAL
;
232 ev
.sigev_signo
= SIGRTMIN
;
233 ev
.sigev_value
.sival_ptr
= &ev
;
234 if (timer_create (TEST_CLOCK
, &ev
, &timer_sig1
) != 0)
236 printf ("*** timer_create for timer_sig1 failed: %m\n");
240 memset (&ev
, 0x33, sizeof (ev
));
241 ev
.sigev_notify
= SIGEV_SIGNAL
;
242 ev
.sigev_signo
= SIGRTMIN
+ 1;
243 ev
.sigev_value
.sival_int
= 163;
244 if (timer_create (TEST_CLOCK
, &ev
, &timer_sig2
) != 0)
246 printf ("*** timer_create for timer_sig2 failed: %m\n");
250 memset (&ev
, 0x44, sizeof (ev
));
251 ev
.sigev_notify
= SIGEV_THREAD
;
252 ev
.sigev_notify_function
= thr1
;
253 ev
.sigev_notify_attributes
= NULL
;
254 ev
.sigev_value
.sival_ptr
= &ev
;
255 if (timer_create (TEST_CLOCK
, &ev
, &timer_thr1
) != 0)
257 printf ("*** timer_create for timer_thr1 failed: %m\n");
261 pthread_attr_t nattr
;
262 if (pthread_attr_init (&nattr
)
263 || pthread_attr_setguardsize (&nattr
, 0))
265 puts ("*** pthread_attr_t setup failed");
269 memset (&ev
, 0x55, sizeof (ev
));
270 ev
.sigev_notify
= SIGEV_THREAD
;
271 ev
.sigev_notify_function
= thr2
;
272 ev
.sigev_notify_attributes
= &nattr
;
273 ev
.sigev_value
.sival_int
= 111;
274 if (timer_create (TEST_CLOCK
, &ev
, &timer_thr2
) != 0)
276 printf ("*** timer_create for timer_thr2 failed: %m\n");
280 int ret
= timer_getoverrun (timer_thr1
);
284 printf ("*** timer_getoverrun failed: %m\n");
286 printf ("*** timer_getoverrun returned %d != 0\n", ret
);
290 struct itimerspec it
;
291 it
.it_value
.tv_sec
= 0;
292 it
.it_value
.tv_nsec
= -26;
293 it
.it_interval
.tv_sec
= 0;
294 it
.it_interval
.tv_nsec
= 0;
295 if (timer_settime (timer_sig1
, 0, &it
, NULL
) == 0)
297 puts ("*** timer_settime with negative tv_nsec unexpectedly succeeded");
300 else if (errno
!= EINVAL
)
302 printf ("*** timer_settime with negative tv_nsec did not fail with "
307 it
.it_value
.tv_nsec
= 100000;
308 it
.it_interval
.tv_nsec
= 1000000000;
309 if (timer_settime (timer_sig2
, 0, &it
, NULL
) == 0)
312 *** timer_settime with tv_nsec 1000000000 unexpectedly succeeded");
315 else if (errno
!= EINVAL
)
317 printf ("*** timer_settime with tv_nsec 1000000000 did not fail with "
323 it
.it_value
.tv_nsec
= 0;
324 it
.it_interval
.tv_nsec
= -26;
325 if (timer_settime (timer_thr1
, 0, &it
, NULL
) != 0)
328 !!! timer_settime with it_value 0 it_interval invalid failed: %m\n");
329 /* FIXME: is this mandated by POSIX?
333 it
.it_interval
.tv_nsec
= 3000000000;
334 if (timer_settime (timer_thr2
, 0, &it
, NULL
) != 0)
337 !!! timer_settime with it_value 0 it_interval invalid failed: %m\n");
338 /* FIXME: is this mandated by POSIX?
343 struct timespec startts
;
344 if (clock_gettime (TEST_CLOCK
, &startts
) != 0)
346 printf ("*** clock_gettime failed: %m\n");
350 it
.it_value
.tv_nsec
= 100000000;
351 it
.it_interval
.tv_nsec
= 0;
352 if (timer_settime (timer_none
, 0, &it
, NULL
) != 0)
354 printf ("*** timer_settime timer_none failed: %m\n");
358 it
.it_value
.tv_nsec
= 200000000;
359 if (timer_settime (timer_thr1
, 0, &it
, NULL
) != 0)
361 printf ("*** timer_settime timer_thr1 failed: %m\n");
365 it
.it_value
.tv_nsec
= 300000000;
366 if (timer_settime (timer_thr2
, 0, &it
, NULL
) != 0)
368 printf ("*** timer_settime timer_thr2 failed: %m\n");
372 it
.it_value
.tv_nsec
= 400000000;
373 if (timer_settime (timer_sig1
, 0, &it
, NULL
) != 0)
375 printf ("*** timer_settime timer_sig1 failed: %m\n");
379 it
.it_value
.tv_nsec
= 500000000;
380 if (TEMP_FAILURE_RETRY (timer_settime (timer_sig2
, 0, &it
, NULL
)) != 0)
382 printf ("*** timer_settime timer_sig2 failed: %m\n");
386 pthread_mutex_lock (&lock
);
387 while (thr1_cnt
== 0 || thr2_cnt
== 0)
388 pthread_cond_wait (&cond
, &lock
);
389 pthread_mutex_unlock (&lock
);
391 while (sig1_cnt
== 0 || sig2_cnt
== 0)
394 ts
.tv_nsec
= 100000000;
395 nanosleep (&ts
, NULL
);
398 pthread_mutex_lock (&lock
);
402 printf ("*** thr1 not called exactly once, but %d times\n", thr1_cnt
);
407 puts ("*** an error occurred in thr1");
410 else if (thr1_sigval
.sival_ptr
!= &ev
)
412 printf ("*** thr1_sigval.sival_ptr %p != %p\n",
413 thr1_sigval
.sival_ptr
, &ev
);
416 else if (check_ts ("thr1", &startts
, &thr1_ts
, 200000))
421 printf ("*** thr2 not called exactly once, but %d times\n", thr2_cnt
);
426 puts ("*** an error occurred in thr2");
429 else if (thr2_sigval
.sival_int
!= 111)
431 printf ("*** thr2_sigval.sival_ptr %d != 111\n", thr2_sigval
.sival_int
);
434 else if (check_ts ("thr2", &startts
, &thr2_ts
, 300000))
436 else if (thr2_guardsize
!= 0)
438 printf ("*** thr2 guardsize %zd != 0\n", thr2_guardsize
);
442 pthread_mutex_unlock (&lock
);
446 printf ("*** sig1 not called exactly once, but %d times\n", sig1_cnt
);
451 printf ("*** errors occurred in sig1 handler %x\n", sig1_err
);
454 else if (sig1_sigval
.sival_ptr
!= &ev
)
456 printf ("*** sig1_sigval.sival_ptr %p != %p\n",
457 sig1_sigval
.sival_ptr
, &ev
);
460 else if (check_ts ("sig1", &startts
, &sig1_ts
, 400000))
465 printf ("*** sig2 not called exactly once, but %d times\n", sig2_cnt
);
470 printf ("*** errors occurred in sig2 handler %x\n", sig2_err
);
473 else if (sig2_sigval
.sival_int
!= 163)
475 printf ("*** sig2_sigval.sival_ptr %d != 163\n", sig2_sigval
.sival_int
);
478 else if (check_ts ("sig2", &startts
, &sig2_ts
, 500000))
481 if (timer_gettime (timer_none
, &it
) != 0)
483 printf ("*** timer_gettime timer_none failed: %m\n");
486 else if (it
.it_value
.tv_sec
|| it
.it_value
.tv_nsec
487 || it
.it_interval
.tv_sec
|| it
.it_interval
.tv_nsec
)
490 *** timer_gettime timer_none returned { %ld.%09jd, %ld.%09jd }\n",
491 (long) it
.it_value
.tv_sec
, (intmax_t) it
.it_value
.tv_nsec
,
492 (long) it
.it_interval
.tv_sec
, (intmax_t) it
.it_interval
.tv_nsec
);
496 if (clock_gettime (TEST_CLOCK
, &startts
) != 0)
498 printf ("*** clock_gettime failed: %m\n");
502 it
.it_value
.tv_sec
= 1;
503 it
.it_value
.tv_nsec
= 0;
504 it
.it_interval
.tv_sec
= 0;
505 it
.it_interval
.tv_nsec
= 100000000;
506 if (timer_settime (timer_none
, 0, &it
, NULL
) != 0)
508 printf ("*** timer_settime timer_none failed: %m\n");
512 it
.it_value
.tv_nsec
= 100000000;
513 it
.it_interval
.tv_nsec
= 200000000;
514 if (timer_settime (timer_thr1
, 0, &it
, NULL
) != 0)
516 printf ("*** timer_settime timer_thr1 failed: %m\n");
520 it
.it_value
.tv_nsec
= 200000000;
521 it
.it_interval
.tv_nsec
= 300000000;
522 if (timer_settime (timer_thr2
, 0, &it
, NULL
) != 0)
524 printf ("*** timer_settime timer_thr2 failed: %m\n");
528 it
.it_value
.tv_nsec
= 300000000;
529 it
.it_interval
.tv_nsec
= 400000000;
530 if (timer_settime (timer_sig1
, 0, &it
, NULL
) != 0)
532 printf ("*** timer_settime timer_sig1 failed: %m\n");
536 it
.it_value
.tv_nsec
= 400000000;
537 it
.it_interval
.tv_nsec
= 500000000;
538 if (TEMP_FAILURE_RETRY (timer_settime (timer_sig2
, 0, &it
, NULL
)) != 0)
540 printf ("*** timer_settime timer_sig2 failed: %m\n");
544 pthread_mutex_lock (&lock
);
545 while (thr1_cnt
< 6 || thr2_cnt
< 6)
546 pthread_cond_wait (&cond
, &lock
);
547 pthread_mutex_unlock (&lock
);
549 while (sig1_cnt
< 6 || sig2_cnt
< 6)
552 ts
.tv_nsec
= 100000000;
553 nanosleep (&ts
, NULL
);
556 pthread_mutex_lock (&lock
);
560 puts ("*** an error occurred in thr1");
563 else if (check_ts ("thr1", &startts
, &thr1_ts
, 1100000 + 4 * 200000))
568 puts ("*** an error occurred in thr2");
571 else if (check_ts ("thr2", &startts
, &thr2_ts
, 1200000 + 4 * 300000))
573 else if (thr2_guardsize
!= 0)
575 printf ("*** thr2 guardsize %zd != 0\n", thr2_guardsize
);
579 pthread_mutex_unlock (&lock
);
583 printf ("*** errors occurred in sig1 handler %x\n", sig1_err
);
586 else if (check_ts ("sig1", &startts
, &sig1_ts
, 1300000 + 4 * 400000))
591 printf ("*** errors occurred in sig2 handler %x\n", sig2_err
);
594 else if (check_ts ("sig2", &startts
, &sig2_ts
, 1400000 + 4 * 500000))
597 if (timer_gettime (timer_none
, &it
) != 0)
599 printf ("*** timer_gettime timer_none failed: %m\n");
602 else if (it
.it_interval
.tv_sec
|| it
.it_interval
.tv_nsec
!= 100000000)
605 !!! second timer_gettime timer_none returned it_interval %ld.%09jd\n",
606 (long) it
.it_interval
.tv_sec
, (intmax_t) it
.it_interval
.tv_nsec
);
607 /* FIXME: For now disabled.
611 if (timer_delete (timer_none
) != 0)
613 printf ("*** timer_delete for timer_none failed: %m\n");
617 if (timer_delete (timer_sig1
) != 0)
619 printf ("*** timer_delete for timer_sig1 failed: %m\n");
623 if (timer_delete (timer_sig2
) != 0)
625 printf ("*** timer_delete for timer_sig2 failed: %m\n");
629 if (timer_delete (timer_thr1
) != 0)
631 printf ("*** timer_delete for timer_thr1 failed: %m\n");
635 if (timer_delete (timer_thr2
) != 0)
637 printf ("*** timer_delete for timer_thr2 failed: %m\n");
643 #elif defined TEST_CLOCK_MISSING
644 /* This just ensures that any functions called in TEST_CLOCK_MISSING
645 are not diagnosed as unused. */
646 # define TEST_FUNCTION (TEST_CLOCK_MISSING (TEST_CLOCK), 0)
648 # define TEST_FUNCTION 0
651 #include "../test-skeleton.c"