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. */
29 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
30 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
32 timer_t timer_none, timer_sig1, timer_sig2, timer_thr1, timer_thr2;
34 int thr1_cnt, thr1_err;
35 union sigval thr1_sigval;
36 struct timespec thr1_ts;
39 thr1 (union sigval sigval)
41 pthread_mutex_lock (&lock);
42 thr1_err = clock_gettime (CLOCK_REALTIME, &thr1_ts);
45 struct itimerspec it = { };
46 thr1_err |= timer_settime (timer_thr1, 0, &it, NULL);
50 pthread_cond_signal (&cond);
51 pthread_mutex_unlock (&lock);
54 int thr2_cnt, thr2_err;
55 union sigval thr2_sigval;
56 size_t thr2_guardsize;
57 struct timespec thr2_ts;
60 thr2 (union sigval sigval)
64 size_t guardsize = -1;
65 int ret = pthread_getattr_np (pthread_self (), &nattr);
69 printf ("pthread_getattr_np failed: %m\n");
74 ret = pthread_attr_getguardsize (&nattr, &guardsize);
78 printf ("pthread_attr_getguardsize failed: %m\n");
81 if (pthread_attr_destroy (&nattr) != 0)
83 puts ("pthread_attr_destroy failed");
87 pthread_mutex_lock (&lock);
88 thr2_err = clock_gettime (CLOCK_REALTIME, &thr2_ts) | err;
91 struct itimerspec it = { };
92 thr2_err |= timer_settime (timer_thr2, 0, &it, NULL);
96 thr2_guardsize = guardsize;
97 pthread_cond_signal (&cond);
98 pthread_mutex_unlock (&lock);
101 volatile int sig1_cnt, sig1_err;
102 volatile union sigval sig1_sigval;
103 struct timespec sig1_ts;
106 sig1_handler (int sig, siginfo_t *info, void *ctx)
109 if (sig != SIGRTMIN) err |= 1 << 0;
110 if (info->si_signo != SIGRTMIN) err |= 1 << 1;
111 if (info->si_code != SI_TIMER) err |= 1 << 2;
112 if (clock_gettime (CLOCK_REALTIME, &sig1_ts) != 0)
116 struct itimerspec it = { };
117 if (timer_settime (timer_sig1, 0, &it, NULL))
121 sig1_sigval = info->si_value;
125 volatile int sig2_cnt, sig2_err;
126 volatile union sigval sig2_sigval;
127 struct timespec sig2_ts;
130 sig2_handler (int sig, siginfo_t *info, void *ctx)
133 if (sig != SIGRTMIN + 1) err |= 1 << 0;
134 if (info->si_signo != SIGRTMIN + 1) err |= 1 << 1;
135 if (info->si_code != SI_TIMER) err |= 1 << 2;
136 if (clock_gettime (CLOCK_REALTIME, &sig2_ts) != 0)
140 struct itimerspec it = { };
141 if (timer_settime (timer_sig2, 0, &it, NULL))
145 sig2_sigval = info->si_value;
149 /* Check if end is later or equal to start + nsec. */
151 check_ts (const char *name, const struct timespec *start,
152 const struct timespec *end, long msec)
154 struct timespec ts = *start;
156 ts.tv_sec += msec / 1000000;
157 ts.tv_nsec += (msec % 1000000) * 1000;
158 if (ts.tv_nsec >= 1000000000)
161 ts.tv_nsec -= 1000000000;
163 if (end->tv_sec < ts.tv_sec
164 || (end->tv_sec == ts.tv_sec && end->tv_nsec < ts.tv_nsec))
166 printf ("timer %s invoked too soon: %ld.%09ld instead of expected %ld.%09ld\n",
167 name, (long) end->tv_sec, end->tv_nsec,
168 (long) ts.tv_sec, ts.tv_nsec);
176 #define TEST_FUNCTION do_test ()
183 if (clock_gettime (CLOCK_REALTIME, &ts) != 0)
185 printf ("clock_gettime failed: %m\n");
189 printf ("clock_gettime returned timespec = { %ld, %ld }\n",
190 (long) ts.tv_sec, ts.tv_nsec);
192 if (clock_getres (CLOCK_REALTIME, &ts) != 0)
194 printf ("clock_getres failed: %m\n");
198 printf ("clock_getres returned timespec = { %ld, %ld }\n",
199 (long) ts.tv_sec, ts.tv_nsec);
202 memset (&ev, 0x11, sizeof (ev));
203 ev.sigev_notify = SIGEV_NONE;
204 if (timer_create (CLOCK_REALTIME, &ev, &timer_none) != 0)
206 printf ("timer_create for timer_none failed: %m\n");
210 struct sigaction sa = { .sa_sigaction = sig1_handler,
211 .sa_flags = SA_SIGINFO };
212 sigemptyset (&sa.sa_mask);
213 sigaction (SIGRTMIN, &sa, NULL);
214 sa.sa_sigaction = sig2_handler;
215 sigaction (SIGRTMIN + 1, &sa, NULL);
217 memset (&ev, 0x22, sizeof (ev));
218 ev.sigev_notify = SIGEV_SIGNAL;
219 ev.sigev_signo = SIGRTMIN;
220 ev.sigev_value.sival_ptr = &ev;
221 if (timer_create (CLOCK_REALTIME, &ev, &timer_sig1) != 0)
223 printf ("timer_create for timer_sig1 failed: %m\n");
227 memset (&ev, 0x33, sizeof (ev));
228 ev.sigev_notify = SIGEV_SIGNAL;
229 ev.sigev_signo = SIGRTMIN + 1;
230 ev.sigev_value.sival_int = 163;
231 if (timer_create (CLOCK_REALTIME, &ev, &timer_sig2) != 0)
233 printf ("timer_create for timer_sig2 failed: %m\n");
237 memset (&ev, 0x44, sizeof (ev));
238 ev.sigev_notify = SIGEV_THREAD;
239 ev.sigev_notify_function = thr1;
240 ev.sigev_notify_attributes = NULL;
241 ev.sigev_value.sival_ptr = &ev;
242 if (timer_create (CLOCK_REALTIME, &ev, &timer_thr1) != 0)
244 printf ("timer_create for timer_thr1 failed: %m\n");
248 pthread_attr_t nattr;
249 if (pthread_attr_init (&nattr)
250 || pthread_attr_setguardsize (&nattr, 0))
252 puts ("pthread_attr_t setup failed");
256 memset (&ev, 0x55, sizeof (ev));
257 ev.sigev_notify = SIGEV_THREAD;
258 ev.sigev_notify_function = thr2;
259 ev.sigev_notify_attributes = &nattr;
260 ev.sigev_value.sival_int = 111;
261 if (timer_create (CLOCK_REALTIME, &ev, &timer_thr2) != 0)
263 printf ("timer_create for timer_thr2 failed: %m\n");
267 int ret = timer_getoverrun (timer_thr1);
271 printf ("timer_getoverrun failed: %m\n");
273 printf ("timer_getoverrun returned %d != 0\n", ret);
277 struct itimerspec it;
278 it.it_value.tv_sec = 0;
279 it.it_value.tv_nsec = -26;
280 it.it_interval.tv_sec = 0;
281 it.it_interval.tv_nsec = 0;
282 if (timer_settime (timer_sig1, 0, &it, NULL) == 0)
284 puts ("timer_settime with negative tv_nsec unexpectedly succeeded");
287 else if (errno != EINVAL)
289 printf ("timer_settime with negative tv_nsec did not fail with "
294 it.it_value.tv_nsec = 100000;
295 it.it_interval.tv_nsec = 1000000000;
296 if (timer_settime (timer_sig2, 0, &it, NULL) == 0)
298 puts ("timer_settime with tv_nsec 1000000000 unexpectedly succeeded");
301 else if (errno != EINVAL)
303 printf ("timer_settime with tv_nsec 1000000000 did not fail with "
308 it.it_value.tv_nsec = 0;
309 it.it_interval.tv_nsec = -26;
310 if (timer_settime (timer_thr1, 0, &it, NULL) != 0)
312 printf ("timer_settime with it_value 0 it_interval invalid failed: %m\n");
313 /* FIXME: is this mandated by POSIX?
317 it.it_interval.tv_nsec = 3000000000;
318 if (timer_settime (timer_thr2, 0, &it, NULL) != 0)
320 printf ("timer_settime with it_value 0 it_interval invalid failed: %m\n");
321 /* FIXME: is this mandated by POSIX?
325 struct timespec startts;
326 if (clock_gettime (CLOCK_REALTIME, &startts) != 0)
328 printf ("clock_gettime failed: %m\n");
332 it.it_value.tv_nsec = 100000000;
333 it.it_interval.tv_nsec = 0;
334 if (timer_settime (timer_none, 0, &it, NULL) != 0)
336 printf ("timer_settime timer_none failed: %m\n");
340 it.it_value.tv_nsec = 200000000;
341 if (timer_settime (timer_thr1, 0, &it, NULL) != 0)
343 printf ("timer_settime timer_thr1 failed: %m\n");
347 it.it_value.tv_nsec = 300000000;
348 if (timer_settime (timer_thr2, 0, &it, NULL) != 0)
350 printf ("timer_settime timer_thr2 failed: %m\n");
354 it.it_value.tv_nsec = 400000000;
355 if (timer_settime (timer_sig1, 0, &it, NULL) != 0)
357 printf ("timer_settime timer_sig1 failed: %m\n");
361 it.it_value.tv_nsec = 500000000;
362 if (TEMP_FAILURE_RETRY (timer_settime (timer_sig2, 0, &it, NULL)) != 0)
364 printf ("timer_settime timer_sig2 failed: %m\n");
368 pthread_mutex_lock (&lock);
369 while (thr1_cnt == 0 || thr2_cnt == 0)
370 pthread_cond_wait (&cond, &lock);
371 pthread_mutex_unlock (&lock);
373 while (sig1_cnt == 0 || sig2_cnt == 0)
376 ts.tv_nsec = 100000000;
377 nanosleep (&ts, NULL);
380 pthread_mutex_lock (&lock);
384 printf ("thr1 not called exactly once, but %d times\n", thr1_cnt);
389 puts ("an error occurred in thr1");
392 else if (thr1_sigval.sival_ptr != &ev)
394 printf ("thr1_sigval.sival_ptr %p != %p\n", thr1_sigval.sival_ptr, &ev);
397 else if (check_ts ("thr1", &startts, &thr1_ts, 200000))
402 printf ("thr2 not called exactly once, but %d times\n", thr2_cnt);
407 puts ("an error occurred in thr2");
410 else if (thr2_sigval.sival_int != 111)
412 printf ("thr2_sigval.sival_ptr %d != 111\n", thr2_sigval.sival_int);
415 else if (check_ts ("thr2", &startts, &thr2_ts, 300000))
417 else if (thr2_guardsize != 0)
419 printf ("thr2 guardsize %zd != 0\n", thr2_guardsize);
423 pthread_mutex_unlock (&lock);
427 printf ("sig1 not called exactly once, but %d times\n", sig1_cnt);
432 printf ("errors occurred in sig1 handler %x\n", sig1_err);
435 else if (sig1_sigval.sival_ptr != &ev)
437 printf ("sig1_sigval.sival_ptr %p != %p\n", sig1_sigval.sival_ptr, &ev);
440 else if (check_ts ("sig1", &startts, &sig1_ts, 400000))
445 printf ("sig2 not called exactly once, but %d times\n", sig2_cnt);
450 printf ("errors occurred in sig2 handler %x\n", sig2_err);
453 else if (sig2_sigval.sival_int != 163)
455 printf ("sig2_sigval.sival_ptr %d != 163\n", sig2_sigval.sival_int);
458 else if (check_ts ("sig2", &startts, &sig2_ts, 500000))
461 if (timer_gettime (timer_none, &it) != 0)
463 printf ("timer_gettime timer_none failed: %m\n");
466 else if (it.it_value.tv_sec || it.it_value.tv_nsec
467 || it.it_interval.tv_sec || it.it_interval.tv_nsec)
469 printf ("timer_gettime timer_none returned { %ld.%09ld, %ld.%09ld }\n",
470 (long) it.it_value.tv_sec, it.it_value.tv_nsec,
471 (long) it.it_interval.tv_sec, it.it_interval.tv_nsec);
475 if (clock_gettime (CLOCK_REALTIME, &startts) != 0)
477 printf ("clock_gettime failed: %m\n");
481 it.it_value.tv_sec = 1;
482 it.it_value.tv_nsec = 0;
483 it.it_interval.tv_sec = 0;
484 it.it_interval.tv_nsec = 100000000;
485 if (timer_settime (timer_none, 0, &it, NULL) != 0)
487 printf ("timer_settime timer_none failed: %m\n");
491 it.it_value.tv_nsec = 100000000;
492 it.it_interval.tv_nsec = 200000000;
493 if (timer_settime (timer_thr1, 0, &it, NULL) != 0)
495 printf ("timer_settime timer_thr1 failed: %m\n");
499 it.it_value.tv_nsec = 200000000;
500 it.it_interval.tv_nsec = 300000000;
501 if (timer_settime (timer_thr2, 0, &it, NULL) != 0)
503 printf ("timer_settime timer_thr2 failed: %m\n");
507 it.it_value.tv_nsec = 300000000;
508 it.it_interval.tv_nsec = 400000000;
509 if (timer_settime (timer_sig1, 0, &it, NULL) != 0)
511 printf ("timer_settime timer_sig1 failed: %m\n");
515 it.it_value.tv_nsec = 400000000;
516 it.it_interval.tv_nsec = 500000000;
517 if (TEMP_FAILURE_RETRY (timer_settime (timer_sig2, 0, &it, NULL)) != 0)
519 printf ("timer_settime timer_sig2 failed: %m\n");
523 pthread_mutex_lock (&lock);
524 while (thr1_cnt < 6 || thr2_cnt < 6)
525 pthread_cond_wait (&cond, &lock);
526 pthread_mutex_unlock (&lock);
528 while (sig1_cnt < 6 || sig2_cnt < 6)
531 ts.tv_nsec = 100000000;
532 nanosleep (&ts, NULL);
535 pthread_mutex_lock (&lock);
539 puts ("an error occurred in thr1");
542 else if (check_ts ("thr1", &startts, &thr1_ts, 1100000 + 4 * 200000))
547 puts ("an error occurred in thr2");
550 else if (check_ts ("thr2", &startts, &thr2_ts, 1200000 + 4 * 300000))
552 else if (thr2_guardsize != 0)
554 printf ("thr2 guardsize %zd != 0\n", thr2_guardsize);
558 pthread_mutex_unlock (&lock);
562 printf ("errors occurred in sig1 handler %x\n", sig1_err);
565 else if (check_ts ("sig1", &startts, &sig1_ts, 1300000 + 4 * 400000))
570 printf ("errors occurred in sig2 handler %x\n", sig2_err);
573 else if (check_ts ("sig2", &startts, &sig2_ts, 1400000 + 4 * 500000))
576 if (timer_gettime (timer_none, &it) != 0)
578 printf ("timer_gettime timer_none failed: %m\n");
581 else if (it.it_interval.tv_sec || it.it_interval.tv_nsec != 100000000)
583 printf ("second timer_gettime timer_none returned it_interval %ld.%09ld\n",
584 (long) it.it_interval.tv_sec, it.it_interval.tv_nsec);
585 /* FIXME: For now disabled.
589 if (timer_delete (timer_none) != 0)
591 printf ("timer_delete for timer_none failed: %m\n");
595 if (timer_delete (timer_sig1) != 0)
597 printf ("timer_delete for timer_sig1 failed: %m\n");
601 if (timer_delete (timer_sig2) != 0)
603 printf ("timer_delete for timer_sig2 failed: %m\n");
607 if (timer_delete (timer_thr1) != 0)
609 printf ("timer_delete for timer_thr1 failed: %m\n");
613 if (timer_delete (timer_thr2) != 0)
615 printf ("timer_delete for timer_thr2 failed: %m\n");
621 # define TEST_FUNCTION 0
624 #include "../test-skeleton.c"