1 /* Test program for process CPU clocks.
2 Copyright (C) 2004-2020 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
29 #include <support/timespec.h>
31 /* This function is intended to rack up both user and system time. */
37 static volatile char buf
[4096];
38 for (int i
= 0; i
< 100; ++i
)
39 for (size_t j
= 0; j
< sizeof buf
; ++j
)
41 int nullfd
= open ("/dev/null", O_WRONLY
);
42 for (int i
= 0; i
< 100; ++i
)
43 for (size_t j
= 0; j
< sizeof buf
; ++j
)
45 write (nullfd
, (char *) buf
, sizeof buf
);
58 pid_t dead_child
, child
;
60 /* Fork a child and let it die, to give us a PID known not be valid
61 (assuming PIDs don't wrap around during the test). */
72 if (wait (&x
) != dead_child
)
79 /* POSIX says we should get ESRCH for this. */
80 e
= clock_getcpuclockid (dead_child
, &cl
);
81 if (e
!= ENOSYS
&& e
!= ESRCH
&& e
!= EPERM
)
83 printf ("clock_getcpuclockid on dead PID %d => %s\n",
84 dead_child
, strerror (e
));
88 /* Now give us a live child eating up CPU time. */
101 e
= clock_getcpuclockid (child
, &cl
);
104 puts ("clock_getcpuclockid does not support other processes");
109 printf ("clock_getcpuclockid on live PID %d => %s\n",
110 child
, strerror (e
));
115 const clockid_t child_clock
= cl
;
117 if (clock_getres (child_clock
, &res
) < 0)
119 printf ("clock_getres on live PID %d clock %lx => %s\n",
120 child
, (unsigned long int) child_clock
, strerror (errno
));
124 printf ("live PID %d clock %lx resolution %ju.%.9ju\n",
125 child
, (unsigned long int) child_clock
,
126 (uintmax_t) res
.tv_sec
, (uintmax_t) res
.tv_nsec
);
128 struct timespec before
, after
;
129 if (clock_gettime (child_clock
, &before
) < 0)
131 printf ("clock_gettime on live PID %d clock %lx => %s\n",
132 child
, (unsigned long int) child_clock
, strerror (errno
));
136 /* Should be close to 0.0. */
137 printf ("live PID %d before sleep => %ju.%.9ju\n",
138 child
, (uintmax_t) before
.tv_sec
, (uintmax_t) before
.tv_nsec
);
140 struct timespec sleeptime
= { .tv_nsec
= 500000000 };
141 if (nanosleep (&sleeptime
, NULL
) != 0)
143 perror ("nanosleep");
148 if (clock_gettime (child_clock
, &after
) < 0)
150 printf ("clock_gettime on live PID %d clock %lx => %s\n",
151 child
, (unsigned long int) child_clock
, strerror (errno
));
155 /* Should be close to 0.5. */
156 printf ("live PID %d after sleep => %ju.%.9ju\n",
157 child
, (uintmax_t) after
.tv_sec
, (uintmax_t) after
.tv_nsec
);
159 /* The bound values are empirically defined by testing this code over high cpu
160 usage and different nice values. Of all the values we keep the 90th
161 percentile of values and use those values for our testing allowed range. */
162 struct timespec diff
= timespec_sub (support_timespec_normalize (after
),
163 support_timespec_normalize (before
));
164 if (!support_timespec_check_in_range (sleeptime
, diff
, .9, 1.1))
166 printf ("before - after %ju.%.9ju outside reasonable range\n",
167 (uintmax_t) diff
.tv_sec
, (uintmax_t) diff
.tv_nsec
);
171 sleeptime
.tv_nsec
= 100000000;
172 e
= clock_nanosleep (child_clock
, 0, &sleeptime
, NULL
);
173 if (e
== EINVAL
|| e
== ENOTSUP
|| e
== ENOSYS
)
175 printf ("clock_nanosleep not supported for other process clock: %s\n",
180 printf ("clock_nanosleep on other process clock: %s\n", strerror (e
));
185 struct timespec afterns
;
186 if (clock_gettime (child_clock
, &afterns
) < 0)
188 printf ("clock_gettime on live PID %d clock %lx => %s\n",
189 child
, (unsigned long int) child_clock
, strerror (errno
));
194 /* The bound values are empirically defined by testing this code over
195 high cpu usage and different nice values. Of all the values we keep
196 the 90th percentile of values and use those values for our testing
198 diff
= timespec_sub (support_timespec_normalize (afterns
),
199 support_timespec_normalize (after
));
200 if (!support_timespec_check_in_range (sleeptime
, diff
, .9, 1.2))
202 printf ("nanosleep time %ju.%.9ju outside reasonable range\n",
203 (uintmax_t) diff
.tv_sec
, (uintmax_t) diff
.tv_nsec
);
209 if (kill (child
, SIGKILL
) != 0)
216 /* Wait long enough to let the child finish dying. */
218 sleeptime
.tv_nsec
= 200000000;
219 if (nanosleep (&sleeptime
, NULL
) != 0)
221 perror ("nanosleep");
226 struct timespec dead
;
227 if (clock_gettime (child_clock
, &dead
) < 0)
229 printf ("clock_gettime on dead PID %d clock %lx => %s\n",
230 child
, (unsigned long int) child_clock
, strerror (errno
));
234 /* Should be close to 0.6. */
235 printf ("dead PID %d => %ju.%.9ju\n",
236 child
, (uintmax_t) dead
.tv_sec
, (uintmax_t) dead
.tv_nsec
);
237 /* The bound values are empirically defined by testing this code over high cpu
238 usage and different nice values. Of all the values we keep the 90th
239 percentile of values and use those values for our testing allowed range. */
240 diff
= timespec_sub (support_timespec_normalize (dead
),
241 support_timespec_normalize (after
));
242 sleeptime
.tv_nsec
= 100000000;
243 if (!support_timespec_check_in_range (sleeptime
, diff
, .9, 1.2))
245 printf ("dead - after %ju.%.9ju outside reasonable range\n",
246 (uintmax_t) diff
.tv_sec
, (uintmax_t) diff
.tv_nsec
);
250 /* Now reap the child and verify that its clock is no longer valid. */
253 if (waitpid (child
, &x
, 0) != child
)
260 if (clock_gettime (child_clock
, &dead
) == 0)
262 printf ("clock_gettime on reaped PID %d clock %lx => %ju%.9ju\n",
263 child
, (unsigned long int) child_clock
,
264 (uintmax_t) dead
.tv_sec
, (uintmax_t) dead
.tv_nsec
);
271 printf ("clock_gettime on reaped PID %d clock %lx => %s\n",
272 child
, (unsigned long int) child_clock
, strerror (errno
));
275 if (clock_getres (child_clock
, &dead
) == 0)
277 printf ("clock_getres on reaped PID %d clock %lx => %ju%.9ju\n",
278 child
, (unsigned long int) child_clock
,
279 (uintmax_t) dead
.tv_sec
, (uintmax_t) dead
.tv_nsec
);
286 printf ("clock_getres on reaped PID %d clock %lx => %s\n",
287 child
, (unsigned long int) child_clock
, strerror (errno
));
294 if (kill (child
, SIGKILL
) != 0 && errno
!= ESRCH
)
300 if (waitpid (child
, &x
, 0) != child
&& errno
!= ECHILD
)
311 #define TEST_FUNCTION do_test ()
312 #include "../test-skeleton.c"