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. */
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;
40 thr1 (union sigval sigval)
42 pthread_mutex_lock (&lock);
43 thr1_err = clock_gettime (CLOCK_REALTIME, &thr1_ts);
46 struct itimerspec it = { };
47 thr1_err |= timer_settime (timer_thr1, 0, &it, NULL);
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;
61 thr2 (union sigval sigval)
65 size_t guardsize = -1;
66 int ret = pthread_getattr_np (pthread_self (), &nattr);
70 printf ("*** pthread_getattr_np failed: %m\n");
75 ret = pthread_attr_getguardsize (&nattr, &guardsize);
79 printf ("*** pthread_attr_getguardsize failed: %m\n");
82 if (pthread_attr_destroy (&nattr) != 0)
84 puts ("*** pthread_attr_destroy failed");
88 pthread_mutex_lock (&lock);
89 thr2_err = clock_gettime (CLOCK_REALTIME, &thr2_ts) | err;
92 struct itimerspec it = { };
93 thr2_err |= timer_settime (timer_thr2, 0, &it, NULL);
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;
107 sig1_handler (int sig, siginfo_t *info, void *ctx)
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)
117 struct itimerspec it = { };
118 if (timer_settime (timer_sig1, 0, &it, NULL))
122 sig1_sigval = info->si_value;
126 volatile int sig2_cnt, sig2_err;
127 volatile union sigval sig2_sigval;
128 struct timespec sig2_ts;
131 sig2_handler (int sig, siginfo_t *info, void *ctx)
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)
141 struct itimerspec it = { };
142 if (timer_settime (timer_sig2, 0, &it, NULL))
146 sig2_sigval = info->si_value;
150 /* Check if end is later or equal to start + nsec. */
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)
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))
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);
178 #define TEST_FUNCTION do_test ()
185 if (clock_gettime (CLOCK_REALTIME, &ts) != 0)
187 printf ("*** clock_gettime failed: %m\n");
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");
200 printf ("clock_getres returned timespec = { %ld, %ld }\n",
201 (long) ts.tv_sec, ts.tv_nsec);
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");
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");
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");
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");
250 pthread_attr_t nattr;
251 if (pthread_attr_init (&nattr)
252 || pthread_attr_setguardsize (&nattr, 0))
254 puts ("*** pthread_attr_t setup failed");
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");
269 int ret = timer_getoverrun (timer_thr1);
273 printf ("*** timer_getoverrun failed: %m\n");
275 printf ("*** timer_getoverrun returned %d != 0\n", ret);
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");
289 else if (errno != EINVAL)
291 printf ("*** timer_settime with negative tv_nsec did not fail with "
296 it.it_value.tv_nsec = 100000;
297 it.it_interval.tv_nsec = 1000000000;
298 if (timer_settime (timer_sig2, 0, &it, NULL) == 0)
301 *** timer_settime with tv_nsec 1000000000 unexpectedly succeeded");
304 else if (errno != EINVAL)
306 printf ("*** timer_settime with tv_nsec 1000000000 did not fail with "
312 it.it_value.tv_nsec = 0;
313 it.it_interval.tv_nsec = -26;
314 if (timer_settime (timer_thr1, 0, &it, NULL) != 0)
317 !!! timer_settime with it_value 0 it_interval invalid failed: %m\n");
318 /* FIXME: is this mandated by POSIX?
322 it.it_interval.tv_nsec = 3000000000;
323 if (timer_settime (timer_thr2, 0, &it, NULL) != 0)
326 !!! timer_settime with it_value 0 it_interval invalid failed: %m\n");
327 /* FIXME: is this mandated by POSIX?
332 struct timespec startts;
333 if (clock_gettime (CLOCK_REALTIME, &startts) != 0)
335 printf ("*** clock_gettime failed: %m\n");
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");
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");
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");
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");
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");
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)
383 ts.tv_nsec = 100000000;
384 nanosleep (&ts, NULL);
387 pthread_mutex_lock (&lock);
391 printf ("*** thr1 not called exactly once, but %d times\n", thr1_cnt);
396 puts ("*** an error occurred in thr1");
399 else if (thr1_sigval.sival_ptr != &ev)
401 printf ("*** thr1_sigval.sival_ptr %p != %p\n",
402 thr1_sigval.sival_ptr, &ev);
405 else if (check_ts ("thr1", &startts, &thr1_ts, 200000))
410 printf ("*** thr2 not called exactly once, but %d times\n", thr2_cnt);
415 puts ("*** an error occurred in thr2");
418 else if (thr2_sigval.sival_int != 111)
420 printf ("*** thr2_sigval.sival_ptr %d != 111\n", thr2_sigval.sival_int);
423 else if (check_ts ("thr2", &startts, &thr2_ts, 300000))
425 else if (thr2_guardsize != 0)
427 printf ("*** thr2 guardsize %zd != 0\n", thr2_guardsize);
431 pthread_mutex_unlock (&lock);
435 printf ("*** sig1 not called exactly once, but %d times\n", sig1_cnt);
440 printf ("*** errors occurred in sig1 handler %x\n", sig1_err);
443 else if (sig1_sigval.sival_ptr != &ev)
445 printf ("*** sig1_sigval.sival_ptr %p != %p\n",
446 sig1_sigval.sival_ptr, &ev);
449 else if (check_ts ("sig1", &startts, &sig1_ts, 400000))
454 printf ("*** sig2 not called exactly once, but %d times\n", sig2_cnt);
459 printf ("*** errors occurred in sig2 handler %x\n", sig2_err);
462 else if (sig2_sigval.sival_int != 163)
464 printf ("*** sig2_sigval.sival_ptr %d != 163\n", sig2_sigval.sival_int);
467 else if (check_ts ("sig2", &startts, &sig2_ts, 500000))
470 if (timer_gettime (timer_none, &it) != 0)
472 printf ("*** timer_gettime timer_none failed: %m\n");
475 else if (it.it_value.tv_sec || it.it_value.tv_nsec
476 || it.it_interval.tv_sec || it.it_interval.tv_nsec)
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);
485 if (clock_gettime (CLOCK_REALTIME, &startts) != 0)
487 printf ("*** clock_gettime failed: %m\n");
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");
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");
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");
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");
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");
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)
541 ts.tv_nsec = 100000000;
542 nanosleep (&ts, NULL);
545 pthread_mutex_lock (&lock);
549 puts ("*** an error occurred in thr1");
552 else if (check_ts ("thr1", &startts, &thr1_ts, 1100000 + 4 * 200000))
557 puts ("*** an error occurred in thr2");
560 else if (check_ts ("thr2", &startts, &thr2_ts, 1200000 + 4 * 300000))
562 else if (thr2_guardsize != 0)
564 printf ("*** thr2 guardsize %zd != 0\n", thr2_guardsize);
568 pthread_mutex_unlock (&lock);
572 printf ("*** errors occurred in sig1 handler %x\n", sig1_err);
575 else if (check_ts ("sig1", &startts, &sig1_ts, 1300000 + 4 * 400000))
580 printf ("*** errors occurred in sig2 handler %x\n", sig2_err);
583 else if (check_ts ("sig2", &startts, &sig2_ts, 1400000 + 4 * 500000))
586 if (timer_gettime (timer_none, &it) != 0)
588 printf ("*** timer_gettime timer_none failed: %m\n");
591 else if (it.it_interval.tv_sec || it.it_interval.tv_nsec != 100000000)
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.
600 if (timer_delete (timer_none) != 0)
602 printf ("*** timer_delete for timer_none failed: %m\n");
606 if (timer_delete (timer_sig1) != 0)
608 printf ("*** timer_delete for timer_sig1 failed: %m\n");
612 if (timer_delete (timer_sig2) != 0)
614 printf ("*** timer_delete for timer_sig2 failed: %m\n");
618 if (timer_delete (timer_thr1) != 0)
620 printf ("*** timer_delete for timer_thr1 failed: %m\n");
624 if (timer_delete (timer_thr2) != 0)
626 printf ("*** timer_delete for timer_thr2 failed: %m\n");
632 # define TEST_FUNCTION 0
635 #include "../test-skeleton.c"