tst-clock_nanosleep2.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /* Test for clock_nanosleep parameter checks and sleep duration.
  2. Copyright (C) 2024-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. /* This test has two primary goals - first, to validate that invalid
  16. inputs to clock_nanosleep are caught, and second, to validate that
  17. clock_nanosleep sleeps for at least the amount of time requested.
  18. It is assumed that the system may sleep for an arbitrary additional
  19. amount of time beyond the requested time. */
  20. #include <unistd.h>
  21. #include <stdint.h>
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <time.h>
  25. #include <fcntl.h>
  26. #include <string.h>
  27. #include <errno.h>
  28. #include <support/xunistd.h>
  29. #include <support/check.h>
  30. #include <support/xthread.h>
  31. #include <support/timespec.h>
  32. /* This is 1 ms per test, we have 10 tests, so this file runs in on
  33. the order of 0.01 seconds. */
  34. #define TEST_NSEC 1000000
  35. /* Nanoseconds per second. */
  36. #define NSECMAX 1000000000L
  37. static pthread_barrier_t barrier;
  38. /* This function is intended to rack up both user and system time. */
  39. static void *
  40. chew_cpu (void *arg)
  41. {
  42. pthread_barrier_wait (&barrier);
  43. while (1)
  44. {
  45. static volatile char buf[4096];
  46. for (int i = 0; i < 100; ++i)
  47. for (size_t j = 0; j < sizeof buf; ++j)
  48. buf[j] = 0xaa;
  49. int nullfd = xopen ("/dev/null", O_WRONLY, 0);
  50. for (int i = 0; i < 100; ++i)
  51. for (size_t j = 0; j < sizeof buf; ++j)
  52. buf[j] = 0xbb;
  53. xwrite (nullfd, (char *) buf, sizeof buf);
  54. close (nullfd);
  55. }
  56. return NULL;
  57. }
  58. static void
  59. ptime_1 (const char *n, struct timespec t)
  60. {
  61. /* This is only for debugging failed test cases. */
  62. printf ("%12s: %lld.%09lld\n", n, (long long int) t.tv_sec,
  63. (long long int) t.tv_nsec);
  64. }
  65. #define ptime(t) ptime_1 (#t, t)
  66. static void
  67. test_interval_1 (const char *n_clock, clockid_t t_clock)
  68. {
  69. struct timespec me_before, me_after, quantum, me_sleep, me_slept;
  70. long long int slept, min_slept;
  71. /* Arbitrary to ensure our time period is sufficiently bigger than
  72. the time step. */
  73. TEST_VERIFY (clock_getres (t_clock, &quantum) == 0);
  74. printf("Clock quantum: %lld ns, test time: %lld ns\n",
  75. (long long int) quantum.tv_nsec, (long long int) TEST_NSEC);
  76. TEST_VERIFY (quantum.tv_nsec <= TEST_NSEC / 10);
  77. min_slept = TEST_NSEC;
  78. me_sleep = make_timespec (0, min_slept);
  79. printf ("test clock %s for %lld.%09lld sec relative\n",
  80. n_clock, (long long int) me_sleep.tv_sec,
  81. (long long int) me_sleep.tv_nsec);
  82. TEST_COMPARE (clock_gettime (t_clock, &me_before), 0);
  83. TEST_COMPARE (clock_nanosleep (t_clock, 0, &me_sleep, NULL), 0);
  84. TEST_COMPARE (clock_gettime (t_clock, &me_after), 0);
  85. me_slept = timespec_sub (me_after, me_before);
  86. slept = support_timespec_ns (me_slept);
  87. ptime (me_before);
  88. ptime (me_after);
  89. ptime (me_sleep);
  90. ptime (me_slept);
  91. printf ("test slept %lld nsec >= asked for %lld ?\n", slept, min_slept);
  92. /* This is the important part - verify that the time slept is at
  93. least as much as the time requested. */
  94. TEST_VERIFY (slept >= min_slept);
  95. }
  96. static void
  97. test_abs_1 (const char *n_clock, clockid_t t_clock)
  98. {
  99. struct timespec me_before, me_after, quantum, me_sleep;
  100. /* Arbitrary to ensure our time period is sufficiently bigger than
  101. the time step. */
  102. TEST_VERIFY (clock_getres (t_clock, &quantum) == 0);
  103. printf("Clock quantum: %lld ns, test time: %lld ns\n",
  104. (long long int) quantum.tv_nsec, (long long int) TEST_NSEC);
  105. TEST_VERIFY (quantum.tv_nsec <= TEST_NSEC / 10);
  106. me_sleep = make_timespec (0, TEST_NSEC);
  107. printf ("test clock %s for %lld.%09lld sec absolute\n",
  108. n_clock, (long long int) me_sleep.tv_sec,
  109. (long long int) me_sleep.tv_nsec);
  110. TEST_COMPARE (clock_gettime (t_clock, &me_before), 0);
  111. me_sleep = timespec_add (me_sleep, me_before);
  112. TEST_COMPARE (clock_nanosleep (t_clock, TIMER_ABSTIME, &me_sleep, NULL), 0);
  113. TEST_COMPARE (clock_gettime (t_clock, &me_after), 0);
  114. ptime (me_before);
  115. ptime (me_sleep);
  116. ptime (me_after);
  117. printf("test slept until %lld.%09lld after requested %lld.%09lld ?\n",
  118. (long long int) me_after.tv_sec, (long long int) me_after.tv_nsec,
  119. (long long int) me_sleep.tv_sec, (long long int) me_sleep.tv_nsec);
  120. /* This is the important part - verify that the time slept is at
  121. least as much as the time requested. */
  122. TEST_TIMESPEC_EQUAL_OR_AFTER (me_after, me_sleep);
  123. }
  124. static void
  125. test_invalids_1 (const char *the_clock_name, int the_clock,
  126. const char *flags_name, int flags)
  127. {
  128. struct timespec me_before;
  129. /* Note: do not use make_timespec() in case that function tries to
  130. normalize the fields. */
  131. printf ("%s: %s: test tv 0, 0\n", the_clock_name, flags_name);
  132. me_before.tv_sec = 0;
  133. me_before.tv_nsec = 0;
  134. TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), 0);
  135. printf ("%s: %s: test tv -1, 0\n", the_clock_name, flags_name);
  136. me_before.tv_sec = -1;
  137. me_before.tv_nsec = 0;
  138. TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), EINVAL);
  139. printf ("%s: %s: test tv 0, -1\n", the_clock_name, flags_name);
  140. me_before.tv_sec = 0;
  141. me_before.tv_nsec = -1;
  142. TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), EINVAL);
  143. printf ("%s: %s: test tv -1, -1\n", the_clock_name, flags_name);
  144. me_before.tv_sec = -1;
  145. me_before.tv_nsec = -1;
  146. TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), EINVAL);
  147. printf ("%s: %s: test tv 0, MAX\n", the_clock_name, flags_name);
  148. me_before.tv_sec = 0;
  149. me_before.tv_nsec = NSECMAX;
  150. TEST_COMPARE (clock_nanosleep (the_clock, 0, &me_before, NULL), EINVAL);
  151. }
  152. static int
  153. do_test (void)
  154. {
  155. pthread_t th;
  156. pthread_barrier_init (&barrier, NULL, 2);
  157. /* Test for proper error detection. */
  158. #define test_invalids(c, f) test_invalids_1 (#c, c, #f, f)
  159. test_invalids (CLOCK_REALTIME, 0);
  160. #ifdef CLOCK_TAI
  161. test_invalids (CLOCK_TAI, 0);
  162. #endif
  163. test_invalids (CLOCK_MONOTONIC, 0);
  164. #ifdef CLOCK_BOOTTIME
  165. test_invalids (CLOCK_BOOTTIME, 0);
  166. #endif
  167. test_invalids (CLOCK_PROCESS_CPUTIME_ID, 0);
  168. test_invalids (CLOCK_REALTIME, TIMER_ABSTIME);
  169. #ifdef CLOCK_TAI
  170. test_invalids (CLOCK_TAI, TIMER_ABSTIME);
  171. #endif
  172. test_invalids (CLOCK_MONOTONIC, TIMER_ABSTIME);
  173. #ifdef CLOCK_BOOTTIME
  174. test_invalids (CLOCK_BOOTTIME, TIMER_ABSTIME);
  175. #endif
  176. test_invalids (CLOCK_PROCESS_CPUTIME_ID, TIMER_ABSTIME);
  177. /* Test for various clocks "working". */
  178. #define test_interval(c) test_interval_1 (#c, c)
  179. test_interval (CLOCK_REALTIME);
  180. #ifdef CLOCK_TAI
  181. test_interval (CLOCK_TAI);
  182. #endif
  183. test_interval (CLOCK_MONOTONIC);
  184. #ifdef CLOCK_BOOTTIME
  185. test_interval (CLOCK_BOOTTIME);
  186. #endif
  187. th = xpthread_create (NULL, chew_cpu, NULL);
  188. xpthread_barrier_wait (&barrier);
  189. test_interval (CLOCK_PROCESS_CPUTIME_ID);
  190. xpthread_cancel (th);
  191. #define test_abs(c) test_abs_1 (#c, c)
  192. test_abs (CLOCK_REALTIME);
  193. #ifdef CLOCK_TAI
  194. test_abs (CLOCK_TAI);
  195. #endif
  196. test_abs (CLOCK_MONOTONIC);
  197. #ifdef CLOCK_BOOTTIME
  198. test_abs (CLOCK_BOOTTIME);
  199. #endif
  200. th = xpthread_create (NULL, chew_cpu, NULL);
  201. xpthread_barrier_wait (&barrier);
  202. test_abs (CLOCK_PROCESS_CPUTIME_ID);
  203. xpthread_cancel (th);
  204. return 0;
  205. }
  206. #include <support/test-driver.c>