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

Unified 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, 4 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tests/clock/clock_irt_test.c ('k') | tests/clock/nacl.scons » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tests/clock/clock_test.c
diff --git a/tests/clock/clock_test.c b/tests/clock/clock_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..cac95c1d97b886c36ee9ec1f8c66b457f12443f5
--- /dev/null
+++ b/tests/clock/clock_test.c
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2013 The Native Client Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "native_client/src/include/nacl_macros.h"
+
+/*
+ * This test resembles the trusted version which can be found in
+ * src/shared/platform/nacl_clock_test.c, but uses the stable ABI
+ * to test the integration correctness. When making changes, please
+ * keep both tests in sync if possible.
+ */
+
+
+/*
+ * 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.
+ * ns constant syscall overhead works fine. On bots, we have to be
+ * much more generous. (This is especially true for qemu-based
+ * testing.)
+ */
+#define NANOS_PER_MICRO (1000)
+#define MICROS_PER_MILLI (1000)
+#define NANOS_PER_MILLI (NANOS_PER_MICRO * MICROS_PER_MILLI)
+#define MICROS_PER_UNIT (1000 * 1000)
+#define NANOS_PER_UNIT (NANOS_PER_MICRO * MICROS_PER_UNIT)
+
+#define DEFAULT_NANOSLEEP_EXTRA_OVERHEAD (10 * NANOS_PER_MILLI)
+#define DEFAULT_NANOSLEEP_EXTRA_FACTOR (100.0)
+#define DEFAULT_NANOSLEEP_TIME (10 * NANOS_PER_MILLI)
+
+/*
+ * Global testing parameters -- fuzziness coefficients in determining
+ * what is considered accurate.
Roland McGrath 2013/08/28 19:54:34 Make these static.
Petr Hosek 2013/08/28 22:48:57 Done.
+ */
+int g_cputime = 1;
+double g_fuzzy_factor = DEFAULT_NANOSLEEP_EXTRA_FACTOR;
+uint64_t g_syscall_overhead = DEFAULT_NANOSLEEP_EXTRA_OVERHEAD;
+uint64_t g_slop_ms = 0;
+
+/*
+ * ClockMonotonicAccuracyTest samples the CLOCK_MONOTONIC
+ * clock before and after invoking NaClNanosleep and computes the time
+ * delta. The test is considered to pass if the time delta is close
+ * to the requested value. "Close" is a per-host-OS attribute, thus
+ * the above testing parameters.
+ */
+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.
+ int num_failures = 0;
+
+ struct timespec t_start;
+ struct timespec t_sleep;
+ struct timespec t_end;
+
+ uint64_t elapsed_nanos;
+ uint64_t elapsed_lower_bound;
+ uint64_t elapsed_upper_bound;
+
+ t_sleep.tv_sec = sleep_nanos / NANOS_PER_UNIT;
+ t_sleep.tv_nsec = sleep_nanos % NANOS_PER_UNIT;
+
+ printf("\nCLOCK_MONOTONIC accuracy test:\n");
+
+ if (0 != clock_gettime(CLOCK_MONOTONIC, &t_start)) {
+ fprintf(stderr, "clock_test: clock_gettime (start) failed, error %d\n",
+ errno);
+ ++num_failures;
+ goto done;
+ }
+ for (;;) {
+ if (0 == nanosleep(&t_sleep, &t_sleep)) {
+ break;
+ }
+ if (EINTR == errno) {
+ /* interrupted syscall: sleep some more */
+ continue;
+ }
+ fprintf(stderr, "clock_test: nanosleep failed, error %d\n",
+ errno);
+ num_failures++;
+ goto done;
+ }
+ if (0 != clock_gettime(CLOCK_MONOTONIC, &t_end)) {
+ fprintf(stderr, "clock_test: clock_gettime (end) failed, error %d\n",
+ errno);
+ return 1;
+ }
+
+ 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.
+ + (t_end.tv_nsec - t_start.tv_nsec) + g_slop_ms * NANOS_PER_MILLI;
+
+ elapsed_lower_bound = sleep_nanos;
+ elapsed_upper_bound = (uint64_t) (sleep_nanos * g_fuzzy_factor
+ + g_syscall_overhead);
+
+ printf("requested sleep: %20"PRIu64" nS\n", sleep_nanos);
+ 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".
+ printf("sleep lower bound: %20"PRIu64" nS\n", elapsed_lower_bound);
+ printf("sleep upper bound: %20"PRIu64" nS\n", elapsed_upper_bound);
+
+ if (elapsed_nanos < elapsed_lower_bound
+ || 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.
+ printf("discrepancy too large\n");
+ num_failures++;
+ }
+ done:
+ printf((0 == num_failures) ? "PASSED\n" : "FAILED\n");
+ return num_failures;
+}
+
+/*
+ * ClockRealtimeAccuracyTest compares the time returned by
+ * CLOCK_REALTIME against that returned by gettimeofday.
+ */
+int ClockRealtimeAccuracyTest(void) {
+ int num_failures = 0;
+
+ struct timespec t_now_ts;
+ struct timeval t_now_tv;
+
+ uint64_t t_now_ts_nanos;
+ uint64_t t_now_tv_nanos;
+ int64_t t_now_diff_nanos;
+
+ printf("\nCLOCK_REALTIME accuracy test:\n");
+
+ if (0 != clock_gettime(CLOCK_REALTIME, &t_now_ts)) {
+ fprintf(stderr, "clock_test: clock_gettime (now) failed, error %d\n",
+ errno);
+ num_failures++;
+ goto done;
+ }
+ if (0 != gettimeofday(&t_now_tv, NULL)) {
+ fprintf(stderr, "clock_test: gettimeofday (now) failed, error %d\n",
+ errno);
+ num_failures++;
+ goto done;
+ }
+
+ t_now_ts_nanos = t_now_ts.tv_sec * NANOS_PER_UNIT + t_now_ts.tv_nsec;
+ t_now_tv_nanos = t_now_tv.tv_sec * NANOS_PER_UNIT
+ + 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.
+
+ printf("clock_gettime: %20"PRIu64" nS\n", t_now_ts_nanos);
+ printf("gettimeofday: %20"PRIu64" nS\n", t_now_tv_nanos);
+
+ t_now_diff_nanos = t_now_ts_nanos - t_now_tv_nanos;
+ if (t_now_diff_nanos < 0) {
+ t_now_diff_nanos = -t_now_diff_nanos;
+ }
+ printf("time difference: %20"PRId64" nS\n", t_now_diff_nanos);
+
+ if (t_now_ts_nanos < g_syscall_overhead) {
+ printf("discrepancy too large\n");
+ num_failures++;
+ }
+ done:
+ printf((0 == num_failures) ? "PASSED\n" : "FAILED\n");
+ return num_failures;
+}
+
+struct ThreadInfo {
+ size_t cycles;
+ struct timespec thread_time;
+ struct timespec process_time;
+ int num_failures;
+};
+
+void *ThreadFunction(void *ptr) {
+ size_t i;
+ struct ThreadInfo *info = (struct ThreadInfo *) ptr;
+
+ 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.
+ __sync_synchronize();
+ }
+
+ if (0 != clock_gettime(CLOCK_THREAD_CPUTIME_ID, &info->thread_time)) {
+ fprintf(stderr, "clock_test: clock_gettime (now) failed, error %d\n",
+ errno);
+ info->num_failures++;
+ return NULL;
+ }
+
+ if (0 != clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &info->process_time)) {
+ fprintf(stderr, "clock_test: clock_gettime (now) failed, error %d\n",
+ errno);
+ info->num_failures++;
+ return NULL;
+ }
+
+ return NULL;
+}
+
+int ClockCpuTimeAccuracyTest(void) {
+ int num_failures = 0;
+
+ int err;
+ struct timespec t_process_start;
+ struct timespec t_process_end;
+ struct timespec t_thread_start;
+ struct timespec t_thread_end;
+
+ uint64_t thread_elapsed = 0;
+ uint64_t process_elapsed = 0;
+ uint64_t child_thread_elapsed = 0;
+ uint64_t elapsed_lower_bound;
+ uint64_t elapsed_upper_bound;
+
+ size_t i;
+ struct ThreadInfo info[10];
+ pthread_t thread[10];
+
+ printf("\nCLOCK_PROCESS/THREAD_CPUTIME_ID accuracy test:\n");
+
+ if (0 != clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t_thread_start)) {
+ fprintf(stderr, "clock_test: clock_gettime (now) failed, error %d\n",
+ errno);
+ num_failures++;
+ goto done;
+ }
+
+ if (0 != clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t_process_start)) {
+ fprintf(stderr, "clock_test: clock_gettime (now) failed, error %d\n",
+ errno);
+ num_failures++;
+ goto done;
+ }
+
+ for (i = 0; i < NACL_ARRAY_SIZE(thread); i++) {
+ memset(&info[i], 0, sizeof info[i]);
+ info[i].cycles = i * 10000000;
+ if (0 != (err = pthread_create(&thread[i], NULL,
+ ThreadFunction, &info[i]))) {
+ fprintf(stderr, "clock_test: pthread_create failed, error %d\n",
+ err);
+ num_failures++;
+ goto done;
+ }
+ }
+
+ for (i = 0; i < NACL_ARRAY_SIZE(thread); i++) {
+ if (0 != (err = pthread_join(thread[i], NULL))) {
+ fprintf(stderr, "clock_test: pthread_join failed, error %d\n",
+ err);
+ num_failures++;
+ goto done;
+ }
+ }
+
+ if (0 != clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t_process_end)) {
+ fprintf(stderr, "clock_test: clock_gettime (now) failed, error %d\n",
+ errno);
+ num_failures++;
+ goto done;
+ }
+
+ if (0 != clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t_thread_end)) {
+ fprintf(stderr, "clock_test: clock_gettime (now) failed, error %d\n",
+ errno);
+ num_failures++;
+ goto done;
+ }
+
+ thread_elapsed =
+ (t_thread_end.tv_sec - t_thread_start.tv_sec) * NANOS_PER_UNIT
+ + (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.
+
+ process_elapsed =
+ (t_process_end.tv_sec - t_process_start.tv_sec) * NANOS_PER_UNIT
+ + (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.
+
+ for (i = 0; i < NACL_ARRAY_SIZE(thread); i++) {
+ uint64_t thread_elapsed_nanos;
+ uint64_t process_elapsed_nanos;
+
+ if (info[i].num_failures > 0) {
+ num_failures += info[i].num_failures;
+ goto done;
+ }
+
+ thread_elapsed_nanos = info[i].thread_time.tv_sec * NANOS_PER_UNIT
+ + info[i].thread_time.tv_nsec;
Roland McGrath 2013/08/28 19:54:34 again
Petr Hosek 2013/08/28 22:48:57 Fixed.
+ process_elapsed_nanos = info[i].process_time.tv_sec * NANOS_PER_UNIT
+ + info[i].process_time.tv_nsec;
Roland McGrath 2013/08/28 19:54:34 again
Petr Hosek 2013/08/28 22:48:57 Fixed.
+ printf("%zd: thread=%20"PRIu64" nS, process=%20"PRIu64" nS\n",
+ i, thread_elapsed_nanos, process_elapsed_nanos);
+ child_thread_elapsed += thread_elapsed_nanos;
+ }
+
+ elapsed_lower_bound = thread_elapsed + child_thread_elapsed;
+ elapsed_upper_bound = (uint64_t) (thread_elapsed
+ + 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.
+
+ printf("thread time: %20"PRIu64" nS\n", thread_elapsed);
+ printf("process time: %20"PRIu64" nS\n", process_elapsed);
+ printf("child thread time: %20"PRIu64" nS\n", child_thread_elapsed);
+ printf("elapsed lower bound: %20"PRIu64" nS\n", elapsed_lower_bound);
+ printf("elapsed upper bound: %20"PRIu64" nS\n", elapsed_upper_bound);
+
+ if (process_elapsed < elapsed_lower_bound
+ || elapsed_upper_bound < process_elapsed) {
Roland McGrath 2013/08/28 19:54:34 again
Petr Hosek 2013/08/28 22:48:57 Fixed.
+ printf("discrepancy too large\n");
+ num_failures++;
+ }
+ done:
+ printf((0 == num_failures) ? "PASSED\n" : "FAILED\n");
+ return num_failures;
+}
+
+int main(int ac, char **av) {
+ uint64_t sleep_nanos = DEFAULT_NANOSLEEP_TIME;
+ int opt;
+ uint32_t num_failures = 0;
+
+ while (-1 != (opt = getopt(ac, av, "cf:o:s:S:"))) {
+ switch (opt) {
+ case 'c':
+ g_cputime = 0;
+ break;
+ case 'f':
+ g_fuzzy_factor = strtod(optarg, (char **) NULL);
+ break;
+ case 'o':
+ g_syscall_overhead = strtoul(optarg, (char **) NULL, 0);
+ break;
+ case 's':
+ g_slop_ms = strtoul(optarg, (char **) NULL, 0);
+ break;
+ case 'S':
+ sleep_nanos = strtoul(optarg, (char **) NULL, 0);
+ break;
+ default:
+ fprintf(stderr, "clock_test: unrecognized option `%c'.\n",
+ opt);
+ fprintf(stderr,
+ "Usage: clock_test [-f fuzz_factor] [-s sleep_nanos]\n"
+ " [-o syscall_overhead_nanos]\n");
+ return -1;
+ }
+ }
+
+ num_failures += ClockMonotonicAccuracyTest(sleep_nanos);
+ num_failures += ClockRealtimeAccuracyTest();
+ if (g_cputime) {
+ num_failures += ClockCpuTimeAccuracyTest();
+ }
+
+ return num_failures;
+}
« 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