1 /* Tests for POSIX timer implementation.
2 Copyright (C) 2004-2016 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Jakub Jelinek <jakub@redhat.com>, 2004
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If
18 not, see <http://www.gnu.org/licenses/>. */
27 #if _POSIX_THREADS && defined SA_SIGINFO
31 # define TEST_CLOCK CLOCK_REALTIME
34 pthread_mutex_t lock
= PTHREAD_MUTEX_INITIALIZER
;
35 pthread_cond_t cond
= PTHREAD_COND_INITIALIZER
;
37 timer_t timer_none
, timer_sig1
, timer_sig2
, timer_thr1
, timer_thr2
;
39 int thr1_cnt
, thr1_err
;
40 union sigval thr1_sigval
;
41 struct timespec thr1_ts
;
44 thr1 (union sigval sigval
)
46 pthread_mutex_lock (&lock
);
47 thr1_err
= clock_gettime (TEST_CLOCK
, &thr1_ts
);
50 struct itimerspec it
= { };
51 thr1_err
|= timer_settime (timer_thr1
, 0, &it
, NULL
);
55 pthread_cond_signal (&cond
);
56 pthread_mutex_unlock (&lock
);
59 int thr2_cnt
, thr2_err
;
60 union sigval thr2_sigval
;
61 size_t thr2_guardsize
;
62 struct timespec thr2_ts
;
65 thr2 (union sigval sigval
)
69 size_t guardsize
= -1;
70 int ret
= pthread_getattr_np (pthread_self (), &nattr
);
74 printf ("*** pthread_getattr_np failed: %m\n");
79 ret
= pthread_attr_getguardsize (&nattr
, &guardsize
);
83 printf ("*** pthread_attr_getguardsize failed: %m\n");
86 if (pthread_attr_destroy (&nattr
) != 0)
88 puts ("*** pthread_attr_destroy failed");
92 pthread_mutex_lock (&lock
);
93 thr2_err
= clock_gettime (TEST_CLOCK
, &thr2_ts
) | err
;
96 struct itimerspec it
= { };
97 thr2_err
|= timer_settime (timer_thr2
, 0, &it
, NULL
);
101 thr2_guardsize
= guardsize
;
102 pthread_cond_signal (&cond
);
103 pthread_mutex_unlock (&lock
);
106 volatile int sig1_cnt
, sig1_err
;
107 volatile union sigval sig1_sigval
;
108 struct timespec sig1_ts
;
111 sig1_handler (int sig
, siginfo_t
*info
, void *ctx
)
114 if (sig
!= SIGRTMIN
) err
|= 1 << 0;
115 if (info
->si_signo
!= SIGRTMIN
) err
|= 1 << 1;
116 if (info
->si_code
!= SI_TIMER
) err
|= 1 << 2;
117 if (clock_gettime (TEST_CLOCK
, &sig1_ts
) != 0)
121 struct itimerspec it
= { };
122 if (timer_settime (timer_sig1
, 0, &it
, NULL
))
126 sig1_sigval
= info
->si_value
;
130 volatile int sig2_cnt
, sig2_err
;
131 volatile union sigval sig2_sigval
;
132 struct timespec sig2_ts
;
135 sig2_handler (int sig
, siginfo_t
*info
, void *ctx
)
138 if (sig
!= SIGRTMIN
+ 1) err
|= 1 << 0;
139 if (info
->si_signo
!= SIGRTMIN
+ 1) err
|= 1 << 1;
140 if (info
->si_code
!= SI_TIMER
) err
|= 1 << 2;
141 if (clock_gettime (TEST_CLOCK
, &sig2_ts
) != 0)
145 struct itimerspec it
= { };
146 if (timer_settime (timer_sig2
, 0, &it
, NULL
))
150 sig2_sigval
= info
->si_value
;
154 /* Check if end is later or equal to start + nsec. */
156 check_ts (const char *name
, const struct timespec
*start
,
157 const struct timespec
*end
, long msec
)
159 struct timespec ts
= *start
;
161 ts
.tv_sec
+= msec
/ 1000000;
162 ts
.tv_nsec
+= (msec
% 1000000) * 1000;
163 if (ts
.tv_nsec
>= 1000000000)
166 ts
.tv_nsec
-= 1000000000;
168 if (end
->tv_sec
< ts
.tv_sec
169 || (end
->tv_sec
== ts
.tv_sec
&& end
->tv_nsec
< ts
.tv_nsec
))
172 *** timer %s invoked too soon: %ld.%09jd instead of expected %ld.%09jd\n",
173 name
, (long) end
->tv_sec
, (intmax_t) end
->tv_nsec
,
174 (long) ts
.tv_sec
, (intmax_t) ts
.tv_nsec
);
182 #define TEST_FUNCTION do_test ()
188 #ifdef TEST_CLOCK_MISSING
189 const char *missing
= TEST_CLOCK_MISSING (TEST_CLOCK
);
192 printf ("%s missing, skipping test\n", missing
);
198 if (clock_gettime (TEST_CLOCK
, &ts
) != 0)
200 printf ("*** clock_gettime failed: %m\n");
204 printf ("clock_gettime returned timespec = { %ld, %jd }\n",
205 (long) ts
.tv_sec
, (intmax_t) ts
.tv_nsec
);
207 if (clock_getres (TEST_CLOCK
, &ts
) != 0)
209 printf ("*** clock_getres failed: %m\n");
213 printf ("clock_getres returned timespec = { %ld, %jd }\n",
214 (long) ts
.tv_sec
, (intmax_t) ts
.tv_nsec
);
217 memset (&ev
, 0x11, sizeof (ev
));
218 ev
.sigev_notify
= SIGEV_NONE
;
219 if (timer_create (TEST_CLOCK
, &ev
, &timer_none
) != 0)
221 printf ("*** timer_create for timer_none failed: %m\n");
225 struct sigaction sa
= { .sa_sigaction
= sig1_handler
,
226 .sa_flags
= SA_SIGINFO
};
227 sigemptyset (&sa
.sa_mask
);
228 sigaction (SIGRTMIN
, &sa
, NULL
);
229 sa
.sa_sigaction
= sig2_handler
;
230 sigaction (SIGRTMIN
+ 1, &sa
, NULL
);
232 memset (&ev
, 0x22, sizeof (ev
));
233 ev
.sigev_notify
= SIGEV_SIGNAL
;
234 ev
.sigev_signo
= SIGRTMIN
;
235 ev
.sigev_value
.sival_ptr
= &ev
;
236 if (timer_create (TEST_CLOCK
, &ev
, &timer_sig1
) != 0)
238 printf ("*** timer_create for timer_sig1 failed: %m\n");
242 memset (&ev
, 0x33, sizeof (ev
));
243 ev
.sigev_notify
= SIGEV_SIGNAL
;
244 ev
.sigev_signo
= SIGRTMIN
+ 1;
245 ev
.sigev_value
.sival_int
= 163;
246 if (timer_create (TEST_CLOCK
, &ev
, &timer_sig2
) != 0)
248 printf ("*** timer_create for timer_sig2 failed: %m\n");
252 memset (&ev
, 0x44, sizeof (ev
));
253 ev
.sigev_notify
= SIGEV_THREAD
;
254 ev
.sigev_notify_function
= thr1
;
255 ev
.sigev_notify_attributes
= NULL
;
256 ev
.sigev_value
.sival_ptr
= &ev
;
257 if (timer_create (TEST_CLOCK
, &ev
, &timer_thr1
) != 0)
259 printf ("*** timer_create for timer_thr1 failed: %m\n");
263 pthread_attr_t nattr
;
264 if (pthread_attr_init (&nattr
)
265 || pthread_attr_setguardsize (&nattr
, 0))
267 puts ("*** pthread_attr_t setup failed");
271 memset (&ev
, 0x55, sizeof (ev
));
272 ev
.sigev_notify
= SIGEV_THREAD
;
273 ev
.sigev_notify_function
= thr2
;
274 ev
.sigev_notify_attributes
= &nattr
;
275 ev
.sigev_value
.sival_int
= 111;
276 if (timer_create (TEST_CLOCK
, &ev
, &timer_thr2
) != 0)
278 printf ("*** timer_create for timer_thr2 failed: %m\n");
282 int ret
= timer_getoverrun (timer_thr1
);
286 printf ("*** timer_getoverrun failed: %m\n");
288 printf ("*** timer_getoverrun returned %d != 0\n", ret
);
292 struct itimerspec it
;
293 it
.it_value
.tv_sec
= 0;
294 it
.it_value
.tv_nsec
= -26;
295 it
.it_interval
.tv_sec
= 0;
296 it
.it_interval
.tv_nsec
= 0;
297 if (timer_settime (timer_sig1
, 0, &it
, NULL
) == 0)
299 puts ("*** timer_settime with negative tv_nsec unexpectedly succeeded");
302 else if (errno
!= EINVAL
)
304 printf ("*** timer_settime with negative tv_nsec did not fail with "
309 it
.it_value
.tv_nsec
= 100000;
310 it
.it_interval
.tv_nsec
= 1000000000;
311 if (timer_settime (timer_sig2
, 0, &it
, NULL
) == 0)
314 *** timer_settime with tv_nsec 1000000000 unexpectedly succeeded");
317 else if (errno
!= EINVAL
)
319 printf ("*** timer_settime with tv_nsec 1000000000 did not fail with "
325 it
.it_value
.tv_nsec
= 0;
326 it
.it_interval
.tv_nsec
= -26;
327 if (timer_settime (timer_thr1
, 0, &it
, NULL
) != 0)
330 !!! timer_settime with it_value 0 it_interval invalid failed: %m\n");
331 /* FIXME: is this mandated by POSIX?
335 it
.it_interval
.tv_nsec
= 3000000000;
336 if (timer_settime (timer_thr2
, 0, &it
, NULL
) != 0)
339 !!! timer_settime with it_value 0 it_interval invalid failed: %m\n");
340 /* FIXME: is this mandated by POSIX?
345 struct timespec startts
;
346 if (clock_gettime (TEST_CLOCK
, &startts
) != 0)
348 printf ("*** clock_gettime failed: %m\n");
352 it
.it_value
.tv_nsec
= 100000000;
353 it
.it_interval
.tv_nsec
= 0;
354 if (timer_settime (timer_none
, 0, &it
, NULL
) != 0)
356 printf ("*** timer_settime timer_none failed: %m\n");
360 it
.it_value
.tv_nsec
= 200000000;
361 if (timer_settime (timer_thr1
, 0, &it
, NULL
) != 0)
363 printf ("*** timer_settime timer_thr1 failed: %m\n");
367 it
.it_value
.tv_nsec
= 300000000;
368 if (timer_settime (timer_thr2
, 0, &it
, NULL
) != 0)
370 printf ("*** timer_settime timer_thr2 failed: %m\n");
374 it
.it_value
.tv_nsec
= 400000000;
375 if (timer_settime (timer_sig1
, 0, &it
, NULL
) != 0)
377 printf ("*** timer_settime timer_sig1 failed: %m\n");
381 it
.it_value
.tv_nsec
= 500000000;
382 if (TEMP_FAILURE_RETRY (timer_settime (timer_sig2
, 0, &it
, NULL
)) != 0)
384 printf ("*** timer_settime timer_sig2 failed: %m\n");
388 pthread_mutex_lock (&lock
);
389 while (thr1_cnt
== 0 || thr2_cnt
== 0)
390 pthread_cond_wait (&cond
, &lock
);
391 pthread_mutex_unlock (&lock
);
393 while (sig1_cnt
== 0 || sig2_cnt
== 0)
396 ts
.tv_nsec
= 100000000;
397 nanosleep (&ts
, NULL
);
400 pthread_mutex_lock (&lock
);
404 printf ("*** thr1 not called exactly once, but %d times\n", thr1_cnt
);
409 puts ("*** an error occurred in thr1");
412 else if (thr1_sigval
.sival_ptr
!= &ev
)
414 printf ("*** thr1_sigval.sival_ptr %p != %p\n",
415 thr1_sigval
.sival_ptr
, &ev
);
418 else if (check_ts ("thr1", &startts
, &thr1_ts
, 200000))
423 printf ("*** thr2 not called exactly once, but %d times\n", thr2_cnt
);
428 puts ("*** an error occurred in thr2");
431 else if (thr2_sigval
.sival_int
!= 111)
433 printf ("*** thr2_sigval.sival_ptr %d != 111\n", thr2_sigval
.sival_int
);
436 else if (check_ts ("thr2", &startts
, &thr2_ts
, 300000))
438 else if (thr2_guardsize
!= 0)
440 printf ("*** thr2 guardsize %zd != 0\n", thr2_guardsize
);
444 pthread_mutex_unlock (&lock
);
448 printf ("*** sig1 not called exactly once, but %d times\n", sig1_cnt
);
453 printf ("*** errors occurred in sig1 handler %x\n", sig1_err
);
456 else if (sig1_sigval
.sival_ptr
!= &ev
)
458 printf ("*** sig1_sigval.sival_ptr %p != %p\n",
459 sig1_sigval
.sival_ptr
, &ev
);
462 else if (check_ts ("sig1", &startts
, &sig1_ts
, 400000))
467 printf ("*** sig2 not called exactly once, but %d times\n", sig2_cnt
);
472 printf ("*** errors occurred in sig2 handler %x\n", sig2_err
);
475 else if (sig2_sigval
.sival_int
!= 163)
477 printf ("*** sig2_sigval.sival_ptr %d != 163\n", sig2_sigval
.sival_int
);
480 else if (check_ts ("sig2", &startts
, &sig2_ts
, 500000))
483 if (timer_gettime (timer_none
, &it
) != 0)
485 printf ("*** timer_gettime timer_none failed: %m\n");
488 else if (it
.it_value
.tv_sec
|| it
.it_value
.tv_nsec
489 || it
.it_interval
.tv_sec
|| it
.it_interval
.tv_nsec
)
492 *** timer_gettime timer_none returned { %ld.%09jd, %ld.%09jd }\n",
493 (long) it
.it_value
.tv_sec
, (intmax_t) it
.it_value
.tv_nsec
,
494 (long) it
.it_interval
.tv_sec
, (intmax_t) it
.it_interval
.tv_nsec
);
498 if (clock_gettime (TEST_CLOCK
, &startts
) != 0)
500 printf ("*** clock_gettime failed: %m\n");
504 it
.it_value
.tv_sec
= 1;
505 it
.it_value
.tv_nsec
= 0;
506 it
.it_interval
.tv_sec
= 0;
507 it
.it_interval
.tv_nsec
= 100000000;
508 if (timer_settime (timer_none
, 0, &it
, NULL
) != 0)
510 printf ("*** timer_settime timer_none failed: %m\n");
514 it
.it_value
.tv_nsec
= 100000000;
515 it
.it_interval
.tv_nsec
= 200000000;
516 if (timer_settime (timer_thr1
, 0, &it
, NULL
) != 0)
518 printf ("*** timer_settime timer_thr1 failed: %m\n");
522 it
.it_value
.tv_nsec
= 200000000;
523 it
.it_interval
.tv_nsec
= 300000000;
524 if (timer_settime (timer_thr2
, 0, &it
, NULL
) != 0)
526 printf ("*** timer_settime timer_thr2 failed: %m\n");
530 it
.it_value
.tv_nsec
= 300000000;
531 it
.it_interval
.tv_nsec
= 400000000;
532 if (timer_settime (timer_sig1
, 0, &it
, NULL
) != 0)
534 printf ("*** timer_settime timer_sig1 failed: %m\n");
538 it
.it_value
.tv_nsec
= 400000000;
539 it
.it_interval
.tv_nsec
= 500000000;
540 if (TEMP_FAILURE_RETRY (timer_settime (timer_sig2
, 0, &it
, NULL
)) != 0)
542 printf ("*** timer_settime timer_sig2 failed: %m\n");
546 pthread_mutex_lock (&lock
);
547 while (thr1_cnt
< 6 || thr2_cnt
< 6)
548 pthread_cond_wait (&cond
, &lock
);
549 pthread_mutex_unlock (&lock
);
551 while (sig1_cnt
< 6 || sig2_cnt
< 6)
554 ts
.tv_nsec
= 100000000;
555 nanosleep (&ts
, NULL
);
558 pthread_mutex_lock (&lock
);
562 puts ("*** an error occurred in thr1");
565 else if (check_ts ("thr1", &startts
, &thr1_ts
, 1100000 + 4 * 200000))
570 puts ("*** an error occurred in thr2");
573 else if (check_ts ("thr2", &startts
, &thr2_ts
, 1200000 + 4 * 300000))
575 else if (thr2_guardsize
!= 0)
577 printf ("*** thr2 guardsize %zd != 0\n", thr2_guardsize
);
581 pthread_mutex_unlock (&lock
);
585 printf ("*** errors occurred in sig1 handler %x\n", sig1_err
);
588 else if (check_ts ("sig1", &startts
, &sig1_ts
, 1300000 + 4 * 400000))
593 printf ("*** errors occurred in sig2 handler %x\n", sig2_err
);
596 else if (check_ts ("sig2", &startts
, &sig2_ts
, 1400000 + 4 * 500000))
599 if (timer_gettime (timer_none
, &it
) != 0)
601 printf ("*** timer_gettime timer_none failed: %m\n");
604 else if (it
.it_interval
.tv_sec
|| it
.it_interval
.tv_nsec
!= 100000000)
607 !!! second timer_gettime timer_none returned it_interval %ld.%09jd\n",
608 (long) it
.it_interval
.tv_sec
, (intmax_t) it
.it_interval
.tv_nsec
);
609 /* FIXME: For now disabled.
613 if (timer_delete (timer_none
) != 0)
615 printf ("*** timer_delete for timer_none failed: %m\n");
619 if (timer_delete (timer_sig1
) != 0)
621 printf ("*** timer_delete for timer_sig1 failed: %m\n");
625 if (timer_delete (timer_sig2
) != 0)
627 printf ("*** timer_delete for timer_sig2 failed: %m\n");
631 if (timer_delete (timer_thr1
) != 0)
633 printf ("*** timer_delete for timer_thr1 failed: %m\n");
637 if (timer_delete (timer_thr2
) != 0)
639 printf ("*** timer_delete for timer_thr2 failed: %m\n");
645 #elif defined TEST_CLOCK_MISSING
646 /* This just ensures that any functions called in TEST_CLOCK_MISSING
647 are not diagnosed as unused. */
648 # define TEST_FUNCTION (TEST_CLOCK_MISSING (TEST_CLOCK), 0)
650 # define TEST_FUNCTION 0
653 #include "../test-skeleton.c"