]> git.ipfire.org Git - thirdparty/glibc.git/blob - rt/tst-timer4.c
Linux: Move aio_read, aio_read64 into libc
[thirdparty/glibc.git] / rt / tst-timer4.c
1 /* Tests for POSIX timer implementation.
2 Copyright (C) 2004-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Jakub Jelinek <jakub@redhat.com>, 2004
5
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.
10
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.
15
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 <https://www.gnu.org/licenses/>. */
19
20 #include <errno.h>
21 #include <signal.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <time.h>
25 #include <unistd.h>
26 #include <stdint.h>
27 #if _POSIX_THREADS && defined SA_SIGINFO
28 # include <pthread.h>
29
30 # ifndef TEST_CLOCK
31 # define TEST_CLOCK CLOCK_REALTIME
32 # endif
33
34 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
35 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
36
37 timer_t timer_none, timer_sig1, timer_sig2, timer_thr1, timer_thr2;
38
39 int thr1_cnt, thr1_err;
40 union sigval thr1_sigval;
41 struct timespec thr1_ts;
42
43 static void
44 thr1 (union sigval sigval)
45 {
46 pthread_mutex_lock (&lock);
47 thr1_err = clock_gettime (TEST_CLOCK, &thr1_ts);
48 if (thr1_cnt >= 5)
49 {
50 struct itimerspec it = { };
51 thr1_err |= timer_settime (timer_thr1, 0, &it, NULL);
52 }
53 thr1_sigval = sigval;
54 ++thr1_cnt;
55 pthread_cond_signal (&cond);
56 pthread_mutex_unlock (&lock);
57 }
58
59 int thr2_cnt, thr2_err;
60 union sigval thr2_sigval;
61 size_t thr2_guardsize;
62 struct timespec thr2_ts;
63
64 static void
65 thr2 (union sigval sigval)
66 {
67 pthread_attr_t nattr;
68 int err = 0;
69 size_t guardsize = -1;
70 int ret = pthread_getattr_np (pthread_self (), &nattr);
71 if (ret)
72 {
73 errno = ret;
74 printf ("*** pthread_getattr_np failed: %m\n");
75 err = 1;
76 }
77 else
78 {
79 ret = pthread_attr_getguardsize (&nattr, &guardsize);
80 if (ret)
81 {
82 errno = ret;
83 printf ("*** pthread_attr_getguardsize failed: %m\n");
84 err = 1;
85 }
86 if (pthread_attr_destroy (&nattr) != 0)
87 {
88 puts ("*** pthread_attr_destroy failed");
89 err = 1;
90 }
91 }
92 pthread_mutex_lock (&lock);
93 thr2_err = clock_gettime (TEST_CLOCK, &thr2_ts) | err;
94 if (thr2_cnt >= 5)
95 {
96 struct itimerspec it = { };
97 thr2_err |= timer_settime (timer_thr2, 0, &it, NULL);
98 }
99 thr2_sigval = sigval;
100 ++thr2_cnt;
101 thr2_guardsize = guardsize;
102 pthread_cond_signal (&cond);
103 pthread_mutex_unlock (&lock);
104 }
105
106 volatile int sig1_cnt, sig1_err;
107 volatile union sigval sig1_sigval;
108 struct timespec sig1_ts;
109
110 static void
111 sig1_handler (int sig, siginfo_t *info, void *ctx)
112 {
113 int err = 0;
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)
118 err |= 1 << 3;
119 if (sig1_cnt >= 5)
120 {
121 struct itimerspec it = { };
122 if (timer_settime (timer_sig1, 0, &it, NULL))
123 err |= 1 << 4;
124 }
125 sig1_err |= err;
126 sig1_sigval = info->si_value;
127 ++sig1_cnt;
128 }
129
130 volatile int sig2_cnt, sig2_err;
131 volatile union sigval sig2_sigval;
132 struct timespec sig2_ts;
133
134 static void
135 sig2_handler (int sig, siginfo_t *info, void *ctx)
136 {
137 int err = 0;
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)
142 err |= 1 << 3;
143 if (sig2_cnt >= 5)
144 {
145 struct itimerspec it = { };
146 if (timer_settime (timer_sig2, 0, &it, NULL))
147 err |= 1 << 4;
148 }
149 sig2_err |= err;
150 sig2_sigval = info->si_value;
151 ++sig2_cnt;
152 }
153
154 /* Check if end is later or equal to start + nsec. */
155 static int
156 check_ts (const char *name, const struct timespec *start,
157 const struct timespec *end, long msec)
158 {
159 struct timespec ts = *start;
160
161 ts.tv_sec += msec / 1000000;
162 ts.tv_nsec += (msec % 1000000) * 1000;
163 if (ts.tv_nsec >= 1000000000)
164 {
165 ++ts.tv_sec;
166 ts.tv_nsec -= 1000000000;
167 }
168 if (end->tv_sec < ts.tv_sec
169 || (end->tv_sec == ts.tv_sec && end->tv_nsec < ts.tv_nsec))
170 {
171 printf ("\
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);
175 return 1;
176 }
177 else
178 return 0;
179 }
180
181 #define TEST_FUNCTION do_test ()
182 static int
183 do_test (void)
184 {
185 int result = 0;
186
187 #ifdef TEST_CLOCK_MISSING
188 const char *missing = TEST_CLOCK_MISSING (TEST_CLOCK);
189 if (missing != NULL)
190 {
191 printf ("%s missing, skipping test\n", missing);
192 return 0;
193 }
194 #endif
195
196 struct timespec ts;
197 if (clock_gettime (TEST_CLOCK, &ts) != 0)
198 {
199 printf ("*** clock_gettime failed: %m\n");
200 result = 1;
201 }
202 else
203 printf ("clock_gettime returned timespec = { %ld, %jd }\n",
204 (long) ts.tv_sec, (intmax_t) ts.tv_nsec);
205
206 if (clock_getres (TEST_CLOCK, &ts) != 0)
207 {
208 printf ("*** clock_getres failed: %m\n");
209 result = 1;
210 }
211 else
212 printf ("clock_getres returned timespec = { %ld, %jd }\n",
213 (long) ts.tv_sec, (intmax_t) ts.tv_nsec);
214
215 struct sigevent ev;
216 memset (&ev, 0x11, sizeof (ev));
217 ev.sigev_notify = SIGEV_NONE;
218 if (timer_create (TEST_CLOCK, &ev, &timer_none) != 0)
219 {
220 printf ("*** timer_create for timer_none failed: %m\n");
221 return 1;
222 }
223
224 struct sigaction sa = { .sa_sigaction = sig1_handler,
225 .sa_flags = SA_SIGINFO };
226 sigemptyset (&sa.sa_mask);
227 sigaction (SIGRTMIN, &sa, NULL);
228 sa.sa_sigaction = sig2_handler;
229 sigaction (SIGRTMIN + 1, &sa, NULL);
230
231 memset (&ev, 0x22, sizeof (ev));
232 ev.sigev_notify = SIGEV_SIGNAL;
233 ev.sigev_signo = SIGRTMIN;
234 ev.sigev_value.sival_ptr = &ev;
235 if (timer_create (TEST_CLOCK, &ev, &timer_sig1) != 0)
236 {
237 printf ("*** timer_create for timer_sig1 failed: %m\n");
238 return 1;
239 }
240
241 memset (&ev, 0x33, sizeof (ev));
242 ev.sigev_notify = SIGEV_SIGNAL;
243 ev.sigev_signo = SIGRTMIN + 1;
244 ev.sigev_value.sival_int = 163;
245 if (timer_create (TEST_CLOCK, &ev, &timer_sig2) != 0)
246 {
247 printf ("*** timer_create for timer_sig2 failed: %m\n");
248 return 1;
249 }
250
251 memset (&ev, 0x44, sizeof (ev));
252 ev.sigev_notify = SIGEV_THREAD;
253 ev.sigev_notify_function = thr1;
254 ev.sigev_notify_attributes = NULL;
255 ev.sigev_value.sival_ptr = &ev;
256 if (timer_create (TEST_CLOCK, &ev, &timer_thr1) != 0)
257 {
258 printf ("*** timer_create for timer_thr1 failed: %m\n");
259 return 1;
260 }
261
262 pthread_attr_t nattr;
263 if (pthread_attr_init (&nattr)
264 || pthread_attr_setguardsize (&nattr, 0))
265 {
266 puts ("*** pthread_attr_t setup failed");
267 result = 1;
268 }
269
270 memset (&ev, 0x55, sizeof (ev));
271 ev.sigev_notify = SIGEV_THREAD;
272 ev.sigev_notify_function = thr2;
273 ev.sigev_notify_attributes = &nattr;
274 ev.sigev_value.sival_int = 111;
275 if (timer_create (TEST_CLOCK, &ev, &timer_thr2) != 0)
276 {
277 printf ("*** timer_create for timer_thr2 failed: %m\n");
278 return 1;
279 }
280
281 int ret = timer_getoverrun (timer_thr1);
282 if (ret != 0)
283 {
284 if (ret == -1)
285 printf ("*** timer_getoverrun failed: %m\n");
286 else
287 printf ("*** timer_getoverrun returned %d != 0\n", ret);
288 result = 1;
289 }
290
291 struct itimerspec it;
292 it.it_value.tv_sec = 0;
293 it.it_value.tv_nsec = -26;
294 it.it_interval.tv_sec = 0;
295 it.it_interval.tv_nsec = 0;
296 if (timer_settime (timer_sig1, 0, &it, NULL) == 0)
297 {
298 puts ("*** timer_settime with negative tv_nsec unexpectedly succeeded");
299 result = 1;
300 }
301 else if (errno != EINVAL)
302 {
303 printf ("*** timer_settime with negative tv_nsec did not fail with "
304 "EINVAL: %m\n");
305 result = 1;
306 }
307
308 it.it_value.tv_nsec = 100000;
309 it.it_interval.tv_nsec = 1000000000;
310 if (timer_settime (timer_sig2, 0, &it, NULL) == 0)
311 {
312 puts ("\
313 *** timer_settime with tv_nsec 1000000000 unexpectedly succeeded");
314 result = 1;
315 }
316 else if (errno != EINVAL)
317 {
318 printf ("*** timer_settime with tv_nsec 1000000000 did not fail with "
319 "EINVAL: %m\n");
320 result = 1;
321 }
322
323 #if 0
324 it.it_value.tv_nsec = 0;
325 it.it_interval.tv_nsec = -26;
326 if (timer_settime (timer_thr1, 0, &it, NULL) != 0)
327 {
328 printf ("\
329 !!! timer_settime with it_value 0 it_interval invalid failed: %m\n");
330 /* FIXME: is this mandated by POSIX?
331 result = 1; */
332 }
333
334 it.it_interval.tv_nsec = 3000000000;
335 if (timer_settime (timer_thr2, 0, &it, NULL) != 0)
336 {
337 printf ("\
338 !!! timer_settime with it_value 0 it_interval invalid failed: %m\n");
339 /* FIXME: is this mandated by POSIX?
340 result = 1; */
341 }
342 #endif
343
344 struct timespec startts;
345 if (clock_gettime (TEST_CLOCK, &startts) != 0)
346 {
347 printf ("*** clock_gettime failed: %m\n");
348 result = 1;
349 }
350
351 it.it_value.tv_nsec = 100000000;
352 it.it_interval.tv_nsec = 0;
353 if (timer_settime (timer_none, 0, &it, NULL) != 0)
354 {
355 printf ("*** timer_settime timer_none failed: %m\n");
356 result = 1;
357 }
358
359 it.it_value.tv_nsec = 200000000;
360 if (timer_settime (timer_thr1, 0, &it, NULL) != 0)
361 {
362 printf ("*** timer_settime timer_thr1 failed: %m\n");
363 result = 1;
364 }
365
366 it.it_value.tv_nsec = 300000000;
367 if (timer_settime (timer_thr2, 0, &it, NULL) != 0)
368 {
369 printf ("*** timer_settime timer_thr2 failed: %m\n");
370 result = 1;
371 }
372
373 it.it_value.tv_nsec = 400000000;
374 if (timer_settime (timer_sig1, 0, &it, NULL) != 0)
375 {
376 printf ("*** timer_settime timer_sig1 failed: %m\n");
377 result = 1;
378 }
379
380 it.it_value.tv_nsec = 500000000;
381 if (TEMP_FAILURE_RETRY (timer_settime (timer_sig2, 0, &it, NULL)) != 0)
382 {
383 printf ("*** timer_settime timer_sig2 failed: %m\n");
384 result = 1;
385 }
386
387 pthread_mutex_lock (&lock);
388 while (thr1_cnt == 0 || thr2_cnt == 0)
389 pthread_cond_wait (&cond, &lock);
390 pthread_mutex_unlock (&lock);
391
392 while (sig1_cnt == 0 || sig2_cnt == 0)
393 {
394 ts.tv_sec = 0;
395 ts.tv_nsec = 100000000;
396 nanosleep (&ts, NULL);
397 }
398
399 pthread_mutex_lock (&lock);
400
401 if (thr1_cnt != 1)
402 {
403 printf ("*** thr1 not called exactly once, but %d times\n", thr1_cnt);
404 result = 1;
405 }
406 else if (thr1_err)
407 {
408 puts ("*** an error occurred in thr1");
409 result = 1;
410 }
411 else if (thr1_sigval.sival_ptr != &ev)
412 {
413 printf ("*** thr1_sigval.sival_ptr %p != %p\n",
414 thr1_sigval.sival_ptr, &ev);
415 result = 1;
416 }
417 else if (check_ts ("thr1", &startts, &thr1_ts, 200000))
418 result = 1;
419
420 if (thr2_cnt != 1)
421 {
422 printf ("*** thr2 not called exactly once, but %d times\n", thr2_cnt);
423 result = 1;
424 }
425 else if (thr2_err)
426 {
427 puts ("*** an error occurred in thr2");
428 result = 1;
429 }
430 else if (thr2_sigval.sival_int != 111)
431 {
432 printf ("*** thr2_sigval.sival_ptr %d != 111\n", thr2_sigval.sival_int);
433 result = 1;
434 }
435 else if (check_ts ("thr2", &startts, &thr2_ts, 300000))
436 result = 1;
437 else if (thr2_guardsize != 0)
438 {
439 printf ("*** thr2 guardsize %zd != 0\n", thr2_guardsize);
440 result = 1;
441 }
442
443 pthread_mutex_unlock (&lock);
444
445 if (sig1_cnt != 1)
446 {
447 printf ("*** sig1 not called exactly once, but %d times\n", sig1_cnt);
448 result = 1;
449 }
450 else if (sig1_err)
451 {
452 printf ("*** errors occurred in sig1 handler %x\n", sig1_err);
453 result = 1;
454 }
455 else if (sig1_sigval.sival_ptr != &ev)
456 {
457 printf ("*** sig1_sigval.sival_ptr %p != %p\n",
458 sig1_sigval.sival_ptr, &ev);
459 result = 1;
460 }
461 else if (check_ts ("sig1", &startts, &sig1_ts, 400000))
462 result = 1;
463
464 if (sig2_cnt != 1)
465 {
466 printf ("*** sig2 not called exactly once, but %d times\n", sig2_cnt);
467 result = 1;
468 }
469 else if (sig2_err)
470 {
471 printf ("*** errors occurred in sig2 handler %x\n", sig2_err);
472 result = 1;
473 }
474 else if (sig2_sigval.sival_int != 163)
475 {
476 printf ("*** sig2_sigval.sival_ptr %d != 163\n", sig2_sigval.sival_int);
477 result = 1;
478 }
479 else if (check_ts ("sig2", &startts, &sig2_ts, 500000))
480 result = 1;
481
482 if (timer_gettime (timer_none, &it) != 0)
483 {
484 printf ("*** timer_gettime timer_none failed: %m\n");
485 result = 1;
486 }
487 else if (it.it_value.tv_sec || it.it_value.tv_nsec
488 || it.it_interval.tv_sec || it.it_interval.tv_nsec)
489 {
490 printf ("\
491 *** timer_gettime timer_none returned { %ld.%09jd, %ld.%09jd }\n",
492 (long) it.it_value.tv_sec, (intmax_t) it.it_value.tv_nsec,
493 (long) it.it_interval.tv_sec, (intmax_t) it.it_interval.tv_nsec);
494 result = 1;
495 }
496
497 if (clock_gettime (TEST_CLOCK, &startts) != 0)
498 {
499 printf ("*** clock_gettime failed: %m\n");
500 result = 1;
501 }
502
503 it.it_value.tv_sec = 1;
504 it.it_value.tv_nsec = 0;
505 it.it_interval.tv_sec = 0;
506 it.it_interval.tv_nsec = 100000000;
507 if (timer_settime (timer_none, 0, &it, NULL) != 0)
508 {
509 printf ("*** timer_settime timer_none failed: %m\n");
510 result = 1;
511 }
512
513 it.it_value.tv_nsec = 100000000;
514 it.it_interval.tv_nsec = 200000000;
515 if (timer_settime (timer_thr1, 0, &it, NULL) != 0)
516 {
517 printf ("*** timer_settime timer_thr1 failed: %m\n");
518 result = 1;
519 }
520
521 it.it_value.tv_nsec = 200000000;
522 it.it_interval.tv_nsec = 300000000;
523 if (timer_settime (timer_thr2, 0, &it, NULL) != 0)
524 {
525 printf ("*** timer_settime timer_thr2 failed: %m\n");
526 result = 1;
527 }
528
529 it.it_value.tv_nsec = 300000000;
530 it.it_interval.tv_nsec = 400000000;
531 if (timer_settime (timer_sig1, 0, &it, NULL) != 0)
532 {
533 printf ("*** timer_settime timer_sig1 failed: %m\n");
534 result = 1;
535 }
536
537 it.it_value.tv_nsec = 400000000;
538 it.it_interval.tv_nsec = 500000000;
539 if (TEMP_FAILURE_RETRY (timer_settime (timer_sig2, 0, &it, NULL)) != 0)
540 {
541 printf ("*** timer_settime timer_sig2 failed: %m\n");
542 result = 1;
543 }
544
545 pthread_mutex_lock (&lock);
546 while (thr1_cnt < 6 || thr2_cnt < 6)
547 pthread_cond_wait (&cond, &lock);
548 pthread_mutex_unlock (&lock);
549
550 while (sig1_cnt < 6 || sig2_cnt < 6)
551 {
552 ts.tv_sec = 0;
553 ts.tv_nsec = 100000000;
554 nanosleep (&ts, NULL);
555 }
556
557 pthread_mutex_lock (&lock);
558
559 if (thr1_err)
560 {
561 puts ("*** an error occurred in thr1");
562 result = 1;
563 }
564 else if (check_ts ("thr1", &startts, &thr1_ts, 1100000 + 4 * 200000))
565 result = 1;
566
567 if (thr2_err)
568 {
569 puts ("*** an error occurred in thr2");
570 result = 1;
571 }
572 else if (check_ts ("thr2", &startts, &thr2_ts, 1200000 + 4 * 300000))
573 result = 1;
574 else if (thr2_guardsize != 0)
575 {
576 printf ("*** thr2 guardsize %zd != 0\n", thr2_guardsize);
577 result = 1;
578 }
579
580 pthread_mutex_unlock (&lock);
581
582 if (sig1_err)
583 {
584 printf ("*** errors occurred in sig1 handler %x\n", sig1_err);
585 result = 1;
586 }
587 else if (check_ts ("sig1", &startts, &sig1_ts, 1300000 + 4 * 400000))
588 result = 1;
589
590 if (sig2_err)
591 {
592 printf ("*** errors occurred in sig2 handler %x\n", sig2_err);
593 result = 1;
594 }
595 else if (check_ts ("sig2", &startts, &sig2_ts, 1400000 + 4 * 500000))
596 result = 1;
597
598 if (timer_gettime (timer_none, &it) != 0)
599 {
600 printf ("*** timer_gettime timer_none failed: %m\n");
601 result = 1;
602 }
603 else if (it.it_interval.tv_sec || it.it_interval.tv_nsec != 100000000)
604 {
605 printf ("\
606 !!! second timer_gettime timer_none returned it_interval %ld.%09jd\n",
607 (long) it.it_interval.tv_sec, (intmax_t) it.it_interval.tv_nsec);
608 /* FIXME: For now disabled.
609 result = 1; */
610 }
611
612 if (timer_delete (timer_none) != 0)
613 {
614 printf ("*** timer_delete for timer_none failed: %m\n");
615 result = 1;
616 }
617
618 if (timer_delete (timer_sig1) != 0)
619 {
620 printf ("*** timer_delete for timer_sig1 failed: %m\n");
621 result = 1;
622 }
623
624 if (timer_delete (timer_sig2) != 0)
625 {
626 printf ("*** timer_delete for timer_sig2 failed: %m\n");
627 result = 1;
628 }
629
630 if (timer_delete (timer_thr1) != 0)
631 {
632 printf ("*** timer_delete for timer_thr1 failed: %m\n");
633 result = 1;
634 }
635
636 if (timer_delete (timer_thr2) != 0)
637 {
638 printf ("*** timer_delete for timer_thr2 failed: %m\n");
639 result = 1;
640 }
641 return result;
642 }
643
644 #elif defined TEST_CLOCK_MISSING
645 /* This just ensures that any functions called in TEST_CLOCK_MISSING
646 are not diagnosed as unused. */
647 # define TEST_FUNCTION (TEST_CLOCK_MISSING (TEST_CLOCK), 0)
648 #else
649 # define TEST_FUNCTION 0
650 #endif
651
652 #include "../test-skeleton.c"