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"