tst-itimer.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /* Basic tests for getitimer and setitimer.
  2. Copyright (C) 2021-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #include <array_length.h>
  16. #include <errno.h>
  17. #include <stdlib.h>
  18. #include <sys/time.h>
  19. #include <support/check.h>
  20. #include <support/support.h>
  21. #include <support/xsignal.h>
  22. #include <unistd.h>
  23. #include <time.h>
  24. static sig_atomic_t cnt;
  25. static void
  26. alrm_handler (int sig)
  27. {
  28. if (++cnt > 3)
  29. cnt = 3;
  30. }
  31. static void
  32. intr_sleep (int sec)
  33. {
  34. struct timespec ts = { .tv_sec = sec, .tv_nsec = 0 };
  35. while (nanosleep (&ts, &ts) == -1 && errno == EINTR)
  36. ;
  37. }
  38. static int
  39. do_test (void)
  40. {
  41. struct itimerval it, it_old;
  42. const int timers[] = { ITIMER_REAL, ITIMER_VIRTUAL, ITIMER_PROF };
  43. for (int i = 0; i < array_length (timers); i++)
  44. {
  45. TEST_COMPARE (getitimer (timers[i], &it), 0);
  46. /* No timer set, all value should be 0. */
  47. TEST_COMPARE (it.it_interval.tv_sec, 0);
  48. TEST_COMPARE (it.it_interval.tv_usec, 0);
  49. TEST_COMPARE (it.it_value.tv_sec, 0);
  50. TEST_COMPARE (it.it_value.tv_usec, 0);
  51. it.it_interval.tv_sec = 10;
  52. it.it_interval.tv_usec = 20;
  53. TEST_COMPARE (setitimer (timers[i], &it, NULL), 0);
  54. TEST_COMPARE (setitimer (timers[i], &(struct itimerval) { }, &it_old),
  55. 0);
  56. /* ITIMER_REAL returns { 0, 0 } for single-shot timers, while
  57. other timers returns setitimer value. */
  58. if (timers[i] == ITIMER_REAL)
  59. {
  60. TEST_COMPARE (it_old.it_interval.tv_sec, 0);
  61. TEST_COMPARE (it_old.it_interval.tv_usec, 0);
  62. }
  63. else
  64. {
  65. TEST_COMPARE (it_old.it_interval.tv_sec, 10);
  66. /* Some systems might use a different precision for ITIMER_VIRTUAL
  67. and ITIMER_IPROF and thus the value might be adjusted. To avoid
  68. trying to guess the resolution, we do not check it. */
  69. }
  70. /* Create a periodic timer and check if the return value is the one
  71. previously set. */
  72. it.it_interval.tv_sec = 10;
  73. it.it_interval.tv_usec = 20;
  74. it.it_value.tv_sec = 30;
  75. it.it_value.tv_usec = 40;
  76. TEST_COMPARE (setitimer (timers[i], &it, NULL), 0);
  77. TEST_COMPARE (setitimer (timers[i], &(struct itimerval) { }, &it_old),
  78. 0);
  79. TEST_COMPARE (it.it_interval.tv_sec, it_old.it_interval.tv_sec);
  80. if (timers[i] == ITIMER_REAL)
  81. TEST_COMPARE (it.it_interval.tv_usec, it_old.it_interval.tv_usec);
  82. if (sizeof (time_t) == 4)
  83. continue;
  84. /* Same as before, but with a 64 bit time_t value. */
  85. it.it_interval.tv_sec = (time_t) 0x1ffffffffull;
  86. it.it_interval.tv_usec = 20;
  87. it.it_value.tv_sec = 0;
  88. it.it_value.tv_usec = 0;
  89. /* Linux does not provide 64 bit time_t support for getitimer and
  90. setitimer on architectures with 32 bit time_t support. */
  91. if (support_itimer_support_time64())
  92. {
  93. TEST_COMPARE (setitimer (timers[i], &it, NULL), 0);
  94. TEST_COMPARE (setitimer (timers[i], &(struct itimerval) { },
  95. &it_old),
  96. 0);
  97. /* ITIMER_REAL returns { 0, 0 } for single-sort timers, while other
  98. timers returns setitimer value. */
  99. if (timers[i] == ITIMER_REAL)
  100. {
  101. TEST_COMPARE (it_old.it_interval.tv_sec, 0ull);
  102. TEST_COMPARE (it_old.it_interval.tv_usec, 0);
  103. }
  104. }
  105. else
  106. {
  107. TEST_COMPARE (setitimer (timers[i], &it, NULL), -1);
  108. TEST_COMPARE (errno, EOVERFLOW);
  109. }
  110. /* Create a periodic timer and check if the return value is the one
  111. previously set. */
  112. it.it_interval.tv_sec = (time_t) 0x1ffffffffull;
  113. it.it_interval.tv_usec = 20;
  114. it.it_value.tv_sec = 30;
  115. it.it_value.tv_usec = 40;
  116. if (support_itimer_support_time64())
  117. {
  118. TEST_COMPARE (setitimer (timers[i], &it, NULL), 0);
  119. TEST_COMPARE (setitimer (timers[i], &(struct itimerval) { },
  120. &it_old),
  121. 0);
  122. if (timers[i] == ITIMER_REAL)
  123. {
  124. TEST_COMPARE (it.it_interval.tv_sec, it_old.it_interval.tv_sec);
  125. TEST_COMPARE (it.it_interval.tv_usec, it_old.it_interval.tv_usec);
  126. }
  127. }
  128. else
  129. {
  130. TEST_COMPARE (setitimer (timers[i], &it, NULL), -1);
  131. TEST_COMPARE (errno, EOVERFLOW);
  132. }
  133. }
  134. {
  135. struct sigaction sa = { .sa_handler = alrm_handler, .sa_flags = 0 };
  136. sigemptyset (&sa.sa_mask);
  137. xsigaction (SIGALRM, &sa, NULL);
  138. }
  139. /* Setup a timer to 0.1s and sleep for 1s and check to 3 signal handler
  140. execution. */
  141. it.it_interval.tv_sec = 0;
  142. it.it_interval.tv_usec = 100000;
  143. it.it_value.tv_sec = 0;
  144. it.it_value.tv_usec = 100000;
  145. /* Check ITIMER_VIRTUAL and ITIMER_PROF would require to generate load
  146. and be subject to system load. */
  147. cnt = 0;
  148. TEST_COMPARE (setitimer (ITIMER_REAL, &it, NULL), 0);
  149. intr_sleep (1);
  150. TEST_COMPARE (cnt, 3);
  151. TEST_COMPARE (setitimer (ITIMER_REAL, &(struct itimerval) { }, NULL), 0);
  152. return 0;
  153. }
  154. #include <support/test-driver.c>