Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(422)

Side by Side Diff: tests/clock/clock_test.c

Issue 23464007: Update glibc revision (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Correct error checking Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tests/clock/clock_irt_test.c ('k') | tests/clock/nacl.scons » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2013 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7 #include <errno.h>
8 #include <inttypes.h>
9 #include <pthread.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <sys/types.h>
13 #include <sys/time.h>
14 #include <time.h>
15 #include <unistd.h>
16
17 #include "native_client/src/include/nacl_macros.h"
18
19 /*
20 * This test resembles the trusted version which can be found in
21 * src/shared/platform/nacl_clock_test.c, but uses the stable ABI
22 * to test the integration correctness. When making changes, please
23 * keep both tests in sync if possible.
24 */
25
26
27 /*
28 * On an unloaded i7, 1ms with a 1.25 fuzziness factor and a 100,000
Roland McGrath 2013/08/28 19:54:34 This comment belongs down a paragraph, right befor
Petr Hosek 2013/08/28 22:48:57 Moved down.
29 * ns constant syscall overhead works fine. On bots, we have to be
30 * much more generous. (This is especially true for qemu-based
31 * testing.)
32 */
33 #define NANOS_PER_MICRO (1000)
34 #define MICROS_PER_MILLI (1000)
35 #define NANOS_PER_MILLI (NANOS_PER_MICRO * MICROS_PER_MILLI)
36 #define MICROS_PER_UNIT (1000 * 1000)
37 #define NANOS_PER_UNIT (NANOS_PER_MICRO * MICROS_PER_UNIT)
38
39 #define DEFAULT_NANOSLEEP_EXTRA_OVERHEAD (10 * NANOS_PER_MILLI)
40 #define DEFAULT_NANOSLEEP_EXTRA_FACTOR (100.0)
41 #define DEFAULT_NANOSLEEP_TIME (10 * NANOS_PER_MILLI)
42
43 /*
44 * Global testing parameters -- fuzziness coefficients in determining
45 * what is considered accurate.
Roland McGrath 2013/08/28 19:54:34 Make these static.
Petr Hosek 2013/08/28 22:48:57 Done.
46 */
47 int g_cputime = 1;
48 double g_fuzzy_factor = DEFAULT_NANOSLEEP_EXTRA_FACTOR;
49 uint64_t g_syscall_overhead = DEFAULT_NANOSLEEP_EXTRA_OVERHEAD;
50 uint64_t g_slop_ms = 0;
51
52 /*
53 * ClockMonotonicAccuracyTest samples the CLOCK_MONOTONIC
54 * clock before and after invoking NaClNanosleep and computes the time
55 * delta. The test is considered to pass if the time delta is close
56 * to the requested value. "Close" is a per-host-OS attribute, thus
57 * the above testing parameters.
58 */
59 int ClockMonotonicAccuracyTest(uint64_t sleep_nanos) {
Roland McGrath 2013/08/28 19:54:34 Make the local functions static.
Petr Hosek 2013/08/28 22:48:57 Done.
60 int num_failures = 0;
61
62 struct timespec t_start;
63 struct timespec t_sleep;
64 struct timespec t_end;
65
66 uint64_t elapsed_nanos;
67 uint64_t elapsed_lower_bound;
68 uint64_t elapsed_upper_bound;
69
70 t_sleep.tv_sec = sleep_nanos / NANOS_PER_UNIT;
71 t_sleep.tv_nsec = sleep_nanos % NANOS_PER_UNIT;
72
73 printf("\nCLOCK_MONOTONIC accuracy test:\n");
74
75 if (0 != clock_gettime(CLOCK_MONOTONIC, &t_start)) {
76 fprintf(stderr, "clock_test: clock_gettime (start) failed, error %d\n",
77 errno);
78 ++num_failures;
79 goto done;
80 }
81 for (;;) {
82 if (0 == nanosleep(&t_sleep, &t_sleep)) {
83 break;
84 }
85 if (EINTR == errno) {
86 /* interrupted syscall: sleep some more */
87 continue;
88 }
89 fprintf(stderr, "clock_test: nanosleep failed, error %d\n",
90 errno);
91 num_failures++;
92 goto done;
93 }
94 if (0 != clock_gettime(CLOCK_MONOTONIC, &t_end)) {
95 fprintf(stderr, "clock_test: clock_gettime (end) failed, error %d\n",
96 errno);
97 return 1;
98 }
99
100 elapsed_nanos = (t_end.tv_sec - t_start.tv_sec) * NANOS_PER_UNIT
Roland McGrath 2013/08/28 19:54:34 Style guide says operator at eol, not next bol.
Petr Hosek 2013/08/28 22:48:57 Fixed.
101 + (t_end.tv_nsec - t_start.tv_nsec) + g_slop_ms * NANOS_PER_MILLI;
102
103 elapsed_lower_bound = sleep_nanos;
104 elapsed_upper_bound = (uint64_t) (sleep_nanos * g_fuzzy_factor
105 + g_syscall_overhead);
106
107 printf("requested sleep: %20"PRIu64" nS\n", sleep_nanos);
108 printf("actual elapsed sleep: %20"PRIu64" nS\n", elapsed_nanos);
Roland McGrath 2013/08/28 19:54:34 This shouldn't report as "actual" a value that inc
Petr Hosek 2013/08/28 22:48:57 Removed the "actual".
109 printf("sleep lower bound: %20"PRIu64" nS\n", elapsed_lower_bound);
110 printf("sleep upper bound: %20"PRIu64" nS\n", elapsed_upper_bound);
111
112 if (elapsed_nanos < elapsed_lower_bound
113 || elapsed_upper_bound < elapsed_nanos) {
Roland McGrath 2013/08/28 19:54:34 operator line break again
Petr Hosek 2013/08/28 22:48:57 Fixed.
114 printf("discrepancy too large\n");
115 num_failures++;
116 }
117 done:
118 printf((0 == num_failures) ? "PASSED\n" : "FAILED\n");
119 return num_failures;
120 }
121
122 /*
123 * ClockRealtimeAccuracyTest compares the time returned by
124 * CLOCK_REALTIME against that returned by gettimeofday.
125 */
126 int ClockRealtimeAccuracyTest(void) {
127 int num_failures = 0;
128
129 struct timespec t_now_ts;
130 struct timeval t_now_tv;
131
132 uint64_t t_now_ts_nanos;
133 uint64_t t_now_tv_nanos;
134 int64_t t_now_diff_nanos;
135
136 printf("\nCLOCK_REALTIME accuracy test:\n");
137
138 if (0 != clock_gettime(CLOCK_REALTIME, &t_now_ts)) {
139 fprintf(stderr, "clock_test: clock_gettime (now) failed, error %d\n",
140 errno);
141 num_failures++;
142 goto done;
143 }
144 if (0 != gettimeofday(&t_now_tv, NULL)) {
145 fprintf(stderr, "clock_test: gettimeofday (now) failed, error %d\n",
146 errno);
147 num_failures++;
148 goto done;
149 }
150
151 t_now_ts_nanos = t_now_ts.tv_sec * NANOS_PER_UNIT + t_now_ts.tv_nsec;
152 t_now_tv_nanos = t_now_tv.tv_sec * NANOS_PER_UNIT
153 + t_now_tv.tv_usec * NANOS_PER_MICRO;
Roland McGrath 2013/08/28 19:54:34 operator line break again
Petr Hosek 2013/08/28 22:48:57 Fixed.
154
155 printf("clock_gettime: %20"PRIu64" nS\n", t_now_ts_nanos);
156 printf("gettimeofday: %20"PRIu64" nS\n", t_now_tv_nanos);
157
158 t_now_diff_nanos = t_now_ts_nanos - t_now_tv_nanos;
159 if (t_now_diff_nanos < 0) {
160 t_now_diff_nanos = -t_now_diff_nanos;
161 }
162 printf("time difference: %20"PRId64" nS\n", t_now_diff_nanos);
163
164 if (t_now_ts_nanos < g_syscall_overhead) {
165 printf("discrepancy too large\n");
166 num_failures++;
167 }
168 done:
169 printf((0 == num_failures) ? "PASSED\n" : "FAILED\n");
170 return num_failures;
171 }
172
173 struct ThreadInfo {
174 size_t cycles;
175 struct timespec thread_time;
176 struct timespec process_time;
177 int num_failures;
178 };
179
180 void *ThreadFunction(void *ptr) {
181 size_t i;
182 struct ThreadInfo *info = (struct ThreadInfo *) ptr;
183
184 for (i = 1; i < info->cycles; i++) {
Roland McGrath 2013/08/28 19:54:34 This should have a comment on its intent.
Petr Hosek 2013/08/28 22:48:57 Added.
185 __sync_synchronize();
186 }
187
188 if (0 != clock_gettime(CLOCK_THREAD_CPUTIME_ID, &info->thread_time)) {
189 fprintf(stderr, "clock_test: clock_gettime (now) failed, error %d\n",
190 errno);
191 info->num_failures++;
192 return NULL;
193 }
194
195 if (0 != clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &info->process_time)) {
196 fprintf(stderr, "clock_test: clock_gettime (now) failed, error %d\n",
197 errno);
198 info->num_failures++;
199 return NULL;
200 }
201
202 return NULL;
203 }
204
205 int ClockCpuTimeAccuracyTest(void) {
206 int num_failures = 0;
207
208 int err;
209 struct timespec t_process_start;
210 struct timespec t_process_end;
211 struct timespec t_thread_start;
212 struct timespec t_thread_end;
213
214 uint64_t thread_elapsed = 0;
215 uint64_t process_elapsed = 0;
216 uint64_t child_thread_elapsed = 0;
217 uint64_t elapsed_lower_bound;
218 uint64_t elapsed_upper_bound;
219
220 size_t i;
221 struct ThreadInfo info[10];
222 pthread_t thread[10];
223
224 printf("\nCLOCK_PROCESS/THREAD_CPUTIME_ID accuracy test:\n");
225
226 if (0 != clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t_thread_start)) {
227 fprintf(stderr, "clock_test: clock_gettime (now) failed, error %d\n",
228 errno);
229 num_failures++;
230 goto done;
231 }
232
233 if (0 != clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t_process_start)) {
234 fprintf(stderr, "clock_test: clock_gettime (now) failed, error %d\n",
235 errno);
236 num_failures++;
237 goto done;
238 }
239
240 for (i = 0; i < NACL_ARRAY_SIZE(thread); i++) {
241 memset(&info[i], 0, sizeof info[i]);
242 info[i].cycles = i * 10000000;
243 if (0 != (err = pthread_create(&thread[i], NULL,
244 ThreadFunction, &info[i]))) {
245 fprintf(stderr, "clock_test: pthread_create failed, error %d\n",
246 err);
247 num_failures++;
248 goto done;
249 }
250 }
251
252 for (i = 0; i < NACL_ARRAY_SIZE(thread); i++) {
253 if (0 != (err = pthread_join(thread[i], NULL))) {
254 fprintf(stderr, "clock_test: pthread_join failed, error %d\n",
255 err);
256 num_failures++;
257 goto done;
258 }
259 }
260
261 if (0 != clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t_process_end)) {
262 fprintf(stderr, "clock_test: clock_gettime (now) failed, error %d\n",
263 errno);
264 num_failures++;
265 goto done;
266 }
267
268 if (0 != clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t_thread_end)) {
269 fprintf(stderr, "clock_test: clock_gettime (now) failed, error %d\n",
270 errno);
271 num_failures++;
272 goto done;
273 }
274
275 thread_elapsed =
276 (t_thread_end.tv_sec - t_thread_start.tv_sec) * NANOS_PER_UNIT
277 + (t_thread_end.tv_nsec - t_thread_start.tv_nsec);
Roland McGrath 2013/08/28 19:54:34 again
Petr Hosek 2013/08/28 22:48:57 Fixed.
278
279 process_elapsed =
280 (t_process_end.tv_sec - t_process_start.tv_sec) * NANOS_PER_UNIT
281 + (t_process_end.tv_nsec - t_process_start.tv_nsec);
Roland McGrath 2013/08/28 19:54:34 again
Petr Hosek 2013/08/28 22:48:57 Fixed.
282
283 for (i = 0; i < NACL_ARRAY_SIZE(thread); i++) {
284 uint64_t thread_elapsed_nanos;
285 uint64_t process_elapsed_nanos;
286
287 if (info[i].num_failures > 0) {
288 num_failures += info[i].num_failures;
289 goto done;
290 }
291
292 thread_elapsed_nanos = info[i].thread_time.tv_sec * NANOS_PER_UNIT
293 + info[i].thread_time.tv_nsec;
Roland McGrath 2013/08/28 19:54:34 again
Petr Hosek 2013/08/28 22:48:57 Fixed.
294 process_elapsed_nanos = info[i].process_time.tv_sec * NANOS_PER_UNIT
295 + info[i].process_time.tv_nsec;
Roland McGrath 2013/08/28 19:54:34 again
Petr Hosek 2013/08/28 22:48:57 Fixed.
296 printf("%zd: thread=%20"PRIu64" nS, process=%20"PRIu64" nS\n",
297 i, thread_elapsed_nanos, process_elapsed_nanos);
298 child_thread_elapsed += thread_elapsed_nanos;
299 }
300
301 elapsed_lower_bound = thread_elapsed + child_thread_elapsed;
302 elapsed_upper_bound = (uint64_t) (thread_elapsed
303 + child_thread_elapsed * g_fuzzy_factor + g_syscall_overhead);
Roland McGrath 2013/08/28 19:54:34 again
Petr Hosek 2013/08/28 22:48:57 Fixed.
304
305 printf("thread time: %20"PRIu64" nS\n", thread_elapsed);
306 printf("process time: %20"PRIu64" nS\n", process_elapsed);
307 printf("child thread time: %20"PRIu64" nS\n", child_thread_elapsed);
308 printf("elapsed lower bound: %20"PRIu64" nS\n", elapsed_lower_bound);
309 printf("elapsed upper bound: %20"PRIu64" nS\n", elapsed_upper_bound);
310
311 if (process_elapsed < elapsed_lower_bound
312 || elapsed_upper_bound < process_elapsed) {
Roland McGrath 2013/08/28 19:54:34 again
Petr Hosek 2013/08/28 22:48:57 Fixed.
313 printf("discrepancy too large\n");
314 num_failures++;
315 }
316 done:
317 printf((0 == num_failures) ? "PASSED\n" : "FAILED\n");
318 return num_failures;
319 }
320
321 int main(int ac, char **av) {
322 uint64_t sleep_nanos = DEFAULT_NANOSLEEP_TIME;
323 int opt;
324 uint32_t num_failures = 0;
325
326 while (-1 != (opt = getopt(ac, av, "cf:o:s:S:"))) {
327 switch (opt) {
328 case 'c':
329 g_cputime = 0;
330 break;
331 case 'f':
332 g_fuzzy_factor = strtod(optarg, (char **) NULL);
333 break;
334 case 'o':
335 g_syscall_overhead = strtoul(optarg, (char **) NULL, 0);
336 break;
337 case 's':
338 g_slop_ms = strtoul(optarg, (char **) NULL, 0);
339 break;
340 case 'S':
341 sleep_nanos = strtoul(optarg, (char **) NULL, 0);
342 break;
343 default:
344 fprintf(stderr, "clock_test: unrecognized option `%c'.\n",
345 opt);
346 fprintf(stderr,
347 "Usage: clock_test [-f fuzz_factor] [-s sleep_nanos]\n"
348 " [-o syscall_overhead_nanos]\n");
349 return -1;
350 }
351 }
352
353 num_failures += ClockMonotonicAccuracyTest(sleep_nanos);
354 num_failures += ClockRealtimeAccuracyTest();
355 if (g_cputime) {
356 num_failures += ClockCpuTimeAccuracyTest();
357 }
358
359 return num_failures;
360 }
OLDNEW
« no previous file with comments | « tests/clock/clock_irt_test.c ('k') | tests/clock/nacl.scons » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698