Update.
[glibc.git] / rt / tst-timer4.c
blob2175211cb61623d374ec57da9468e2a814c8e5ff
1 /* Tests for POSIX timer implementation.
2 Copyright (C) 2004 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 not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #include <errno.h>
22 #include <signal.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <time.h>
26 #include <unistd.h>
27 #if _POSIX_THREADS
28 # include <pthread.h>
30 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
31 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
33 timer_t timer_none, timer_sig1, timer_sig2, timer_thr1, timer_thr2;
35 int thr1_cnt, thr1_err;
36 union sigval thr1_sigval;
37 struct timespec thr1_ts;
39 static void
40 thr1 (union sigval sigval)
42 pthread_mutex_lock (&lock);
43 thr1_err = clock_gettime (CLOCK_REALTIME, &thr1_ts);
44 if (thr1_cnt >= 5)
46 struct itimerspec it = { };
47 thr1_err |= timer_settime (timer_thr1, 0, &it, NULL);
49 thr1_sigval = sigval;
50 ++thr1_cnt;
51 pthread_cond_signal (&cond);
52 pthread_mutex_unlock (&lock);
55 int thr2_cnt, thr2_err;
56 union sigval thr2_sigval;
57 size_t thr2_guardsize;
58 struct timespec thr2_ts;
60 static void
61 thr2 (union sigval sigval)
63 pthread_attr_t nattr;
64 int err = 0;
65 size_t guardsize = -1;
66 int ret = pthread_getattr_np (pthread_self (), &nattr);
67 if (ret)
69 errno = ret;
70 printf ("*** pthread_getattr_np failed: %m\n");
71 err = 1;
73 else
75 ret = pthread_attr_getguardsize (&nattr, &guardsize);
76 if (ret)
78 errno = ret;
79 printf ("*** pthread_attr_getguardsize failed: %m\n");
80 err = 1;
82 if (pthread_attr_destroy (&nattr) != 0)
84 puts ("*** pthread_attr_destroy failed");
85 err = 1;
88 pthread_mutex_lock (&lock);
89 thr2_err = clock_gettime (CLOCK_REALTIME, &thr2_ts) | err;
90 if (thr2_cnt >= 5)
92 struct itimerspec it = { };
93 thr2_err |= timer_settime (timer_thr2, 0, &it, NULL);
95 thr2_sigval = sigval;
96 ++thr2_cnt;
97 thr2_guardsize = guardsize;
98 pthread_cond_signal (&cond);
99 pthread_mutex_unlock (&lock);
102 volatile int sig1_cnt, sig1_err;
103 volatile union sigval sig1_sigval;
104 struct timespec sig1_ts;
106 static void
107 sig1_handler (int sig, siginfo_t *info, void *ctx)
109 int err = 0;
110 if (sig != SIGRTMIN) err |= 1 << 0;
111 if (info->si_signo != SIGRTMIN) err |= 1 << 1;
112 if (info->si_code != SI_TIMER) err |= 1 << 2;
113 if (clock_gettime (CLOCK_REALTIME, &sig1_ts) != 0)
114 err |= 1 << 3;
115 if (sig1_cnt >= 5)
117 struct itimerspec it = { };
118 if (timer_settime (timer_sig1, 0, &it, NULL))
119 err |= 1 << 4;
121 sig1_err |= err;
122 sig1_sigval = info->si_value;
123 ++sig1_cnt;
126 volatile int sig2_cnt, sig2_err;
127 volatile union sigval sig2_sigval;
128 struct timespec sig2_ts;
130 static void
131 sig2_handler (int sig, siginfo_t *info, void *ctx)
133 int err = 0;
134 if (sig != SIGRTMIN + 1) err |= 1 << 0;
135 if (info->si_signo != SIGRTMIN + 1) err |= 1 << 1;
136 if (info->si_code != SI_TIMER) err |= 1 << 2;
137 if (clock_gettime (CLOCK_REALTIME, &sig2_ts) != 0)
138 err |= 1 << 3;
139 if (sig2_cnt >= 5)
141 struct itimerspec it = { };
142 if (timer_settime (timer_sig2, 0, &it, NULL))
143 err |= 1 << 4;
145 sig2_err |= err;
146 sig2_sigval = info->si_value;
147 ++sig2_cnt;
150 /* Check if end is later or equal to start + nsec. */
151 static int
152 check_ts (const char *name, const struct timespec *start,
153 const struct timespec *end, long msec)
155 struct timespec ts = *start;
157 ts.tv_sec += msec / 1000000;
158 ts.tv_nsec += (msec % 1000000) * 1000;
159 if (ts.tv_nsec >= 1000000000)
161 ++ts.tv_sec;
162 ts.tv_nsec -= 1000000000;
164 if (end->tv_sec < ts.tv_sec
165 || (end->tv_sec == ts.tv_sec && end->tv_nsec < ts.tv_nsec))
167 printf ("\
168 *** timer %s invoked too soon: %ld.%09ld instead of expected %ld.%09ld\n",
169 name, (long) end->tv_sec, end->tv_nsec,
170 (long) ts.tv_sec, ts.tv_nsec);
171 return 1;
173 else
174 return 0;
177 #define TIMEOUT 15
178 #define TEST_FUNCTION do_test ()
179 static int
180 do_test (void)
182 int result = 0;
184 struct timespec ts;
185 if (clock_gettime (CLOCK_REALTIME, &ts) != 0)
187 printf ("*** clock_gettime failed: %m\n");
188 result = 1;
190 else
191 printf ("clock_gettime returned timespec = { %ld, %ld }\n",
192 (long) ts.tv_sec, ts.tv_nsec);
194 if (clock_getres (CLOCK_REALTIME, &ts) != 0)
196 printf ("*** clock_getres failed: %m\n");
197 result = 1;
199 else
200 printf ("clock_getres returned timespec = { %ld, %ld }\n",
201 (long) ts.tv_sec, ts.tv_nsec);
203 struct sigevent ev;
204 memset (&ev, 0x11, sizeof (ev));
205 ev.sigev_notify = SIGEV_NONE;
206 if (timer_create (CLOCK_REALTIME, &ev, &timer_none) != 0)
208 printf ("*** timer_create for timer_none failed: %m\n");
209 result = 1;
212 struct sigaction sa = { .sa_sigaction = sig1_handler,
213 .sa_flags = SA_SIGINFO };
214 sigemptyset (&sa.sa_mask);
215 sigaction (SIGRTMIN, &sa, NULL);
216 sa.sa_sigaction = sig2_handler;
217 sigaction (SIGRTMIN + 1, &sa, NULL);
219 memset (&ev, 0x22, sizeof (ev));
220 ev.sigev_notify = SIGEV_SIGNAL;
221 ev.sigev_signo = SIGRTMIN;
222 ev.sigev_value.sival_ptr = &ev;
223 if (timer_create (CLOCK_REALTIME, &ev, &timer_sig1) != 0)
225 printf ("*** timer_create for timer_sig1 failed: %m\n");
226 result = 1;
229 memset (&ev, 0x33, sizeof (ev));
230 ev.sigev_notify = SIGEV_SIGNAL;
231 ev.sigev_signo = SIGRTMIN + 1;
232 ev.sigev_value.sival_int = 163;
233 if (timer_create (CLOCK_REALTIME, &ev, &timer_sig2) != 0)
235 printf ("*** timer_create for timer_sig2 failed: %m\n");
236 result = 1;
239 memset (&ev, 0x44, sizeof (ev));
240 ev.sigev_notify = SIGEV_THREAD;
241 ev.sigev_notify_function = thr1;
242 ev.sigev_notify_attributes = NULL;
243 ev.sigev_value.sival_ptr = &ev;
244 if (timer_create (CLOCK_REALTIME, &ev, &timer_thr1) != 0)
246 printf ("*** timer_create for timer_thr1 failed: %m\n");
247 result = 1;
250 pthread_attr_t nattr;
251 if (pthread_attr_init (&nattr)
252 || pthread_attr_setguardsize (&nattr, 0))
254 puts ("*** pthread_attr_t setup failed");
255 result = 1;
258 memset (&ev, 0x55, sizeof (ev));
259 ev.sigev_notify = SIGEV_THREAD;
260 ev.sigev_notify_function = thr2;
261 ev.sigev_notify_attributes = &nattr;
262 ev.sigev_value.sival_int = 111;
263 if (timer_create (CLOCK_REALTIME, &ev, &timer_thr2) != 0)
265 printf ("*** timer_create for timer_thr2 failed: %m\n");
266 result = 1;
269 int ret = timer_getoverrun (timer_thr1);
270 if (ret != 0)
272 if (ret == -1)
273 printf ("*** timer_getoverrun failed: %m\n");
274 else
275 printf ("*** timer_getoverrun returned %d != 0\n", ret);
276 result = 1;
279 struct itimerspec it;
280 it.it_value.tv_sec = 0;
281 it.it_value.tv_nsec = -26;
282 it.it_interval.tv_sec = 0;
283 it.it_interval.tv_nsec = 0;
284 if (timer_settime (timer_sig1, 0, &it, NULL) == 0)
286 puts ("*** timer_settime with negative tv_nsec unexpectedly succeeded");
287 result = 1;
289 else if (errno != EINVAL)
291 printf ("*** timer_settime with negative tv_nsec did not fail with "
292 "EINVAL: %m\n");
293 result = 1;
296 it.it_value.tv_nsec = 100000;
297 it.it_interval.tv_nsec = 1000000000;
298 if (timer_settime (timer_sig2, 0, &it, NULL) == 0)
300 puts ("\
301 *** timer_settime with tv_nsec 1000000000 unexpectedly succeeded");
302 result = 1;
304 else if (errno != EINVAL)
306 printf ("*** timer_settime with tv_nsec 1000000000 did not fail with "
307 "EINVAL: %m\n");
308 result = 1;
311 #if 0
312 it.it_value.tv_nsec = 0;
313 it.it_interval.tv_nsec = -26;
314 if (timer_settime (timer_thr1, 0, &it, NULL) != 0)
316 printf ("\
317 !!! timer_settime with it_value 0 it_interval invalid failed: %m\n");
318 /* FIXME: is this mandated by POSIX?
319 result = 1; */
322 it.it_interval.tv_nsec = 3000000000;
323 if (timer_settime (timer_thr2, 0, &it, NULL) != 0)
325 printf ("\
326 !!! timer_settime with it_value 0 it_interval invalid failed: %m\n");
327 /* FIXME: is this mandated by POSIX?
328 result = 1; */
330 #endif
332 struct timespec startts;
333 if (clock_gettime (CLOCK_REALTIME, &startts) != 0)
335 printf ("*** clock_gettime failed: %m\n");
336 result = 1;
339 it.it_value.tv_nsec = 100000000;
340 it.it_interval.tv_nsec = 0;
341 if (timer_settime (timer_none, 0, &it, NULL) != 0)
343 printf ("*** timer_settime timer_none failed: %m\n");
344 result = 1;
347 it.it_value.tv_nsec = 200000000;
348 if (timer_settime (timer_thr1, 0, &it, NULL) != 0)
350 printf ("*** timer_settime timer_thr1 failed: %m\n");
351 result = 1;
354 it.it_value.tv_nsec = 300000000;
355 if (timer_settime (timer_thr2, 0, &it, NULL) != 0)
357 printf ("*** timer_settime timer_thr2 failed: %m\n");
358 result = 1;
361 it.it_value.tv_nsec = 400000000;
362 if (timer_settime (timer_sig1, 0, &it, NULL) != 0)
364 printf ("*** timer_settime timer_sig1 failed: %m\n");
365 result = 1;
368 it.it_value.tv_nsec = 500000000;
369 if (TEMP_FAILURE_RETRY (timer_settime (timer_sig2, 0, &it, NULL)) != 0)
371 printf ("*** timer_settime timer_sig2 failed: %m\n");
372 result = 1;
375 pthread_mutex_lock (&lock);
376 while (thr1_cnt == 0 || thr2_cnt == 0)
377 pthread_cond_wait (&cond, &lock);
378 pthread_mutex_unlock (&lock);
380 while (sig1_cnt == 0 || sig2_cnt == 0)
382 ts.tv_sec = 0;
383 ts.tv_nsec = 100000000;
384 nanosleep (&ts, NULL);
387 pthread_mutex_lock (&lock);
389 if (thr1_cnt != 1)
391 printf ("*** thr1 not called exactly once, but %d times\n", thr1_cnt);
392 result = 1;
394 else if (thr1_err)
396 puts ("*** an error occurred in thr1");
397 result = 1;
399 else if (thr1_sigval.sival_ptr != &ev)
401 printf ("*** thr1_sigval.sival_ptr %p != %p\n",
402 thr1_sigval.sival_ptr, &ev);
403 result = 1;
405 else if (check_ts ("thr1", &startts, &thr1_ts, 200000))
406 result = 1;
408 if (thr2_cnt != 1)
410 printf ("*** thr2 not called exactly once, but %d times\n", thr2_cnt);
411 result = 1;
413 else if (thr2_err)
415 puts ("*** an error occurred in thr2");
416 result = 1;
418 else if (thr2_sigval.sival_int != 111)
420 printf ("*** thr2_sigval.sival_ptr %d != 111\n", thr2_sigval.sival_int);
421 result = 1;
423 else if (check_ts ("thr2", &startts, &thr2_ts, 300000))
424 result = 1;
425 else if (thr2_guardsize != 0)
427 printf ("*** thr2 guardsize %zd != 0\n", thr2_guardsize);
428 result = 1;
431 pthread_mutex_unlock (&lock);
433 if (sig1_cnt != 1)
435 printf ("*** sig1 not called exactly once, but %d times\n", sig1_cnt);
436 result = 1;
438 else if (sig1_err)
440 printf ("*** errors occurred in sig1 handler %x\n", sig1_err);
441 result = 1;
443 else if (sig1_sigval.sival_ptr != &ev)
445 printf ("*** sig1_sigval.sival_ptr %p != %p\n",
446 sig1_sigval.sival_ptr, &ev);
447 result = 1;
449 else if (check_ts ("sig1", &startts, &sig1_ts, 400000))
450 result = 1;
452 if (sig2_cnt != 1)
454 printf ("*** sig2 not called exactly once, but %d times\n", sig2_cnt);
455 result = 1;
457 else if (sig2_err)
459 printf ("*** errors occurred in sig2 handler %x\n", sig2_err);
460 result = 1;
462 else if (sig2_sigval.sival_int != 163)
464 printf ("*** sig2_sigval.sival_ptr %d != 163\n", sig2_sigval.sival_int);
465 result = 1;
467 else if (check_ts ("sig2", &startts, &sig2_ts, 500000))
468 result = 1;
470 if (timer_gettime (timer_none, &it) != 0)
472 printf ("*** timer_gettime timer_none failed: %m\n");
473 result = 1;
475 else if (it.it_value.tv_sec || it.it_value.tv_nsec
476 || it.it_interval.tv_sec || it.it_interval.tv_nsec)
478 printf ("\
479 *** timer_gettime timer_none returned { %ld.%09ld, %ld.%09ld }\n",
480 (long) it.it_value.tv_sec, it.it_value.tv_nsec,
481 (long) it.it_interval.tv_sec, it.it_interval.tv_nsec);
482 result = 1;
485 if (clock_gettime (CLOCK_REALTIME, &startts) != 0)
487 printf ("*** clock_gettime failed: %m\n");
488 result = 1;
491 it.it_value.tv_sec = 1;
492 it.it_value.tv_nsec = 0;
493 it.it_interval.tv_sec = 0;
494 it.it_interval.tv_nsec = 100000000;
495 if (timer_settime (timer_none, 0, &it, NULL) != 0)
497 printf ("*** timer_settime timer_none failed: %m\n");
498 result = 1;
501 it.it_value.tv_nsec = 100000000;
502 it.it_interval.tv_nsec = 200000000;
503 if (timer_settime (timer_thr1, 0, &it, NULL) != 0)
505 printf ("*** timer_settime timer_thr1 failed: %m\n");
506 result = 1;
509 it.it_value.tv_nsec = 200000000;
510 it.it_interval.tv_nsec = 300000000;
511 if (timer_settime (timer_thr2, 0, &it, NULL) != 0)
513 printf ("*** timer_settime timer_thr2 failed: %m\n");
514 result = 1;
517 it.it_value.tv_nsec = 300000000;
518 it.it_interval.tv_nsec = 400000000;
519 if (timer_settime (timer_sig1, 0, &it, NULL) != 0)
521 printf ("*** timer_settime timer_sig1 failed: %m\n");
522 result = 1;
525 it.it_value.tv_nsec = 400000000;
526 it.it_interval.tv_nsec = 500000000;
527 if (TEMP_FAILURE_RETRY (timer_settime (timer_sig2, 0, &it, NULL)) != 0)
529 printf ("*** timer_settime timer_sig2 failed: %m\n");
530 result = 1;
533 pthread_mutex_lock (&lock);
534 while (thr1_cnt < 6 || thr2_cnt < 6)
535 pthread_cond_wait (&cond, &lock);
536 pthread_mutex_unlock (&lock);
538 while (sig1_cnt < 6 || sig2_cnt < 6)
540 ts.tv_sec = 0;
541 ts.tv_nsec = 100000000;
542 nanosleep (&ts, NULL);
545 pthread_mutex_lock (&lock);
547 if (thr1_err)
549 puts ("*** an error occurred in thr1");
550 result = 1;
552 else if (check_ts ("thr1", &startts, &thr1_ts, 1100000 + 4 * 200000))
553 result = 1;
555 if (thr2_err)
557 puts ("*** an error occurred in thr2");
558 result = 1;
560 else if (check_ts ("thr2", &startts, &thr2_ts, 1200000 + 4 * 300000))
561 result = 1;
562 else if (thr2_guardsize != 0)
564 printf ("*** thr2 guardsize %zd != 0\n", thr2_guardsize);
565 result = 1;
568 pthread_mutex_unlock (&lock);
570 if (sig1_err)
572 printf ("*** errors occurred in sig1 handler %x\n", sig1_err);
573 result = 1;
575 else if (check_ts ("sig1", &startts, &sig1_ts, 1300000 + 4 * 400000))
576 result = 1;
578 if (sig2_err)
580 printf ("*** errors occurred in sig2 handler %x\n", sig2_err);
581 result = 1;
583 else if (check_ts ("sig2", &startts, &sig2_ts, 1400000 + 4 * 500000))
584 result = 1;
586 if (timer_gettime (timer_none, &it) != 0)
588 printf ("*** timer_gettime timer_none failed: %m\n");
589 result = 1;
591 else if (it.it_interval.tv_sec || it.it_interval.tv_nsec != 100000000)
593 printf ("\
594 !!! second timer_gettime timer_none returned it_interval %ld.%09ld\n",
595 (long) it.it_interval.tv_sec, it.it_interval.tv_nsec);
596 /* FIXME: For now disabled.
597 result = 1; */
600 if (timer_delete (timer_none) != 0)
602 printf ("*** timer_delete for timer_none failed: %m\n");
603 result = 1;
606 if (timer_delete (timer_sig1) != 0)
608 printf ("*** timer_delete for timer_sig1 failed: %m\n");
609 result = 1;
612 if (timer_delete (timer_sig2) != 0)
614 printf ("*** timer_delete for timer_sig2 failed: %m\n");
615 result = 1;
618 if (timer_delete (timer_thr1) != 0)
620 printf ("*** timer_delete for timer_thr1 failed: %m\n");
621 result = 1;
624 if (timer_delete (timer_thr2) != 0)
626 printf ("*** timer_delete for timer_thr2 failed: %m\n");
627 result = 1;
629 return result;
631 #else
632 # define TEST_FUNCTION 0
633 #endif
635 #include "../test-skeleton.c"