<pre style='margin:0'>
Christopher Nielsen (mascguy) pushed a commit to branch master
in repository macports-legacy-support.

</pre>
<p><a href="https://github.com/macports/macports-legacy-support/commit/a3376c3c9065668237e865b3aa92062345f94f2c">https://github.com/macports/macports-legacy-support/commit/a3376c3c9065668237e865b3aa92062345f94f2c</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit a3376c3c9065668237e865b3aa92062345f94f2c
</span>Author: Fred Wright <fw@fwright.net>
AuthorDate: Thu Mar 27 15:38:00 2025 -0700

<span style='display:block; white-space:pre;color:#404040;'>    Add clock investigative tool.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    TESTED:
</span><span style='display:block; white-space:pre;color:#404040;'>    Works as expected on all platforms.
</span>---
 tools/clock_info.c | 1018 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 1018 insertions(+)

<span style='display:block; white-space:pre;color:#808080;'>diff --git a/tools/clock_info.c b/tools/clock_info.c
</span>new file mode 100644
<span style='display:block; white-space:pre;color:#808080;'>index 0000000..e7257f9
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>--- /dev/null
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/tools/clock_info.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -0,0 +1,1018 @@
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Copyright (c) 2025 Frederick H. G. Wright II <fw@fwright.net>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Permission to use, copy, modify, and distribute this software for any
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * purpose with or without fee is hereby granted, provided that the above
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * copyright notice and this permission notice appear in all copies.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * This is an investigative tool for capturing runs of clock samples and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * reporting a histogram of the deltas, or of diffs/deltas from an interleaved
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * capture of a test clock vs. mach_absolute_time.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * This tool is intended to be built without legacy-support, but can
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * optionally load the legacy-support library from either the "system"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * location or the relative build-tree location.  In the former case,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * the default "/opt/local" prefix is assumed, unless the MPPREFIX
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * definition is overridden.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <assert.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <dlfcn.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <errno.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <libgen.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdint.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdio.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <stdlib.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <string.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <time.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <unistd.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <mach/mach_time.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/param.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/time.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Allow builds with <10.12 SDK (and no legacy-support headers).
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * This a simplified version of the relevant portion of the 10.12 time.h.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifndef CLOCK_REALTIME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef enum {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+_CLOCK_REALTIME = 0,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_REALTIME _CLOCK_REALTIME
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+_CLOCK_MONOTONIC = 6,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_MONOTONIC _CLOCK_MONOTONIC
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+_CLOCK_MONOTONIC_RAW = 4,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_MONOTONIC_RAW _CLOCK_MONOTONIC_RAW
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+_CLOCK_MONOTONIC_RAW_APPROX = 5,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_MONOTONIC_RAW_APPROX _CLOCK_MONOTONIC_RAW_APPROX
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+_CLOCK_UPTIME_RAW = 8,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_UPTIME_RAW _CLOCK_UPTIME_RAW
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+_CLOCK_UPTIME_RAW_APPROX = 9,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_UPTIME_RAW_APPROX _CLOCK_UPTIME_RAW_APPROX
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} clockid_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif /* CLOCK_REALTIME undef */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* RTLD_FIRST is unavailable on 10.4 - make it ignored. */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifndef RTLD_FIRST
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define RTLD_FIRST 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define DEF_NUM_DIFFS 1000
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define DEF_SLEEP_MS  5
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define REF_CLOCK_IDX clock_idx_mach_absolute
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define DEF_CLOCK_IDX REF_CLOCK_IDX
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define MIN_DIFFS 3
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define MAX_DIFFS 1000000
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define MIN_SLEEP 1
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define MAX_SLEEP 1000
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifndef MPPREFIX
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define MPPREFIX "/opt/local"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define LIBDIR "lib"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define LSLIB "libMacportsLegacySupport.dylib"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define MPLSLIB MPPREFIX "/" LIBDIR "/" LSLIB
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define LOCALLSLIB "../" LIBDIR "/" LSLIB
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef uint64_t mach_time_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef struct timeval timeval_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef struct timespec timespec_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef uint64_t ns_time_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef int64_t sns_time_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define BILLION64  1000000000ULL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define UL (unsigned long)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define ULL (unsigned long long)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define LL  (long long)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef mach_time_t (mach_fn_t)(void);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef int (timeofday_fn_t)(timeval_t *, void *);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef int (gettime_fn_t)(clockid_t, timespec_t *);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef ns_time_t (gettime_ns_fn_t)(clockid_t);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * The macros setting up various tables related to clock types are based on
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * macros in test_clocks.c, but creating a common header isn't worth the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * complexity.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* List of clock types */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* #define CLOCK_TYPE(name,valtype) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_TYPES \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  CLOCK_TYPE(mach,mach_time_t) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  CLOCK_TYPE(timeofday,timeval_t) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  CLOCK_TYPE(gettime,timespec_t) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  CLOCK_TYPE(gettime_ns,ns_time_t) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Clock type enums */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_TYPE(name,buf) clock_type_##name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef enum clock_type {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  CLOCK_TYPES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} clock_type_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_TYPE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* List of non-process-specific clocks */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* #define NP_CLOCK(name,type) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define NP_CLOCKS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_TOD_CLOCKS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_MACH_CLOCKS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_GETTIME_CLOCKS(gettime) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_GETTIME_CLOCKS(gettime_ns) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Time of day clock */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define NP_TOD_CLOCKS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCK(timeofday,timeofday) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Mach clocks */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define NP_MACH_CLOCKS \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCK(absolute,mach) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCK(approximate,mach) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCK(continuous,mach) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCK(continuous_approximate,mach) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Gettime clocks (for both flavors) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define NP_GETTIME_CLOCKS(type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCK(REALTIME,type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCK(MONOTONIC,type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCK(MONOTONIC_RAW,type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCK(MONOTONIC_RAW_APPROX,type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCK(UPTIME_RAW,type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCK(UPTIME_RAW_APPROX,type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CALLMAC(a,b,c) a##b(c)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Clock type codes */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_IDX_timeofday(name) clock_idx_##name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_IDX_mach(name) clock_idx_mach_##name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_IDX_gettime(name) clock_idx_gettime_##name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_IDX_gettime_ns(name) clock_idx_gettime_ns_##name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define NP_CLOCK(name,type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  CALLMAC(CLOCK_IDX_,type,name),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef enum clock_idx {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCKS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} clock_idx_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef NP_CLOCK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_IDX_timeofday
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_IDX_mach
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_IDX_gettime
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_IDX_gettime_ns
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define NP_CLOCK(name,type) clock_type_##type,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static const clock_type_t clock_types[] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCKS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef NP_CLOCK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Clock function names */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_FUNC_timeofday(name) "gettimeofday"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_FUNC_mach(name) "mach_" #name "_time"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_FUNC_gettime(name) "clock_gettime"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_FUNC_gettime_ns(name) "clock_gettime_nsec_np"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define NP_CLOCK(name,type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  CALLMAC(CLOCK_FUNC_,type,name),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static const char * const clock_func_names[] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCKS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef NP_CLOCK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_FUNC_timeofday
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_FUNC_mach
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_FUNC_gettime
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_FUNC_gettime_ns
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Arguments for collector functions */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_ARG_timeofday(name) 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_ARG_mach(name) 0
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_ARG_gettime(name) CLOCK_##name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_ARG_gettime_ns(name) CLOCK_##name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define NP_CLOCK(name,type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  CALLMAC(CLOCK_ARG_,type,name),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static const clockid_t clock_ids[] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCKS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef NP_CLOCK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_ARG_timeofday
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_ARG_mach
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_ARG_gettime
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_ARG_gettime_ns
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Clock names */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_NAME_timeofday(name) "timeofday"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_NAME_mach(name) "mach_" #name "_time"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_NAME_gettime(name) "CLOCK_" #name
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_NAME_gettime_ns(name) "CLOCK_" #name "_ns"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define NP_CLOCK(name,type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  CALLMAC(CLOCK_NAME_,type,name),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static const char * const clock_names[] = {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NP_CLOCKS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  NULL
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef NP_CLOCK
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_NAME_timeofday
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_NAME_mach
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_NAME_gettime
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_NAME_gettime_ns
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Union of clock function pointers */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_TYPE(name,valtype) name##_fn_t *name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef union clock_funcp_u {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  CLOCK_TYPES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} clock_funcp_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_TYPE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Union of clock value pointers */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_TYPE(name,valtype) valtype *name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef union clock_bufp_u {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  CLOCK_TYPES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} clock_bufp_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#undef CLOCK_TYPE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Struct for histogram entry */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef struct histent_s {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  sns_time_t diff;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int count;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} histent_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Generic structure for clock info */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef struct clock_info_s {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_idx_t idx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_type_t type;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  long numdiffs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  long sleepus;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_funcp_t f;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clockid_t clkid;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_bufp_t b;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_bufp_t be;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ns_time_t *nsbuf;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ns_time_t *nsbufe;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  histent_t *hbuf;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  histent_t *hbufe;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  sns_time_t mean_diff;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} clock_info_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Mach clock scale factors */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static mach_timebase_info_data_t tbinfo;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static long double mach2nanos, mach2usecs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Bit bucket for cache warmup calls */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static volatile union scratch_u {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  mach_time_t mach;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  timeval_t timeval;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  timespec_t timespec;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ns_time_t ns_time;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} time_scratch;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Set up initial parameters in clock_info */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+setup_info(clock_info_t *ci, clock_idx_t idx, long numdiffs, long sleepms)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ci->idx = idx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ci->type = clock_types[idx];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ci->numdiffs = numdiffs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ci->sleepus = sleepms * 1000;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ci->clkid = clock_ids[idx];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Conversions from different time formats to nanoseconds */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static ns_time_t
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+tv2nsec(timeval_t *tv)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return tv->tv_sec * BILLION64 + tv->tv_usec * 1000;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static ns_time_t
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+mt2nsec(mach_time_t mach_time)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return mach_time * mach2nanos;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static ns_time_t
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ts2nsec(timespec_t *ts)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return ts->tv_sec * BILLION64 + ts->tv_nsec;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Plus a microsecond conversion */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static useconds_t
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+mt2usec(mach_time_t mach_time)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return mach_time * mach2usecs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Mach time in microseconds */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static useconds_t
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+mach_usec(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return mt2usec(mach_absolute_time());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Version of usleep() that defends against signals (just paranoia) */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+usleepx(useconds_t usecs)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  useconds_t now = mach_usec();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  useconds_t target = now + usecs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  do {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    (void) usleep(target - now);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  } while ((now = mach_usec()) < target);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+setup_mach(int verbose)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int err;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if ((err = mach_timebase_info(&tbinfo))) return err;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  mach2nanos = (long double) tbinfo.numer / tbinfo.denom;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  mach2usecs = mach2nanos / 1000.0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (verbose) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("  Scale for mach_time (nanoseconds per unit) is %u/%u = %.3f\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           tbinfo.numer, tbinfo.denom, (double) mach2nanos);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+load_lib(int legacy, char *progname, int verbose)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char *progdir;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char lslib[PATH_MAX], lsreal[PATH_MAX];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  const char *libpath;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  void *libhandle = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (legacy > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    libpath = MPLSLIB;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    progdir = dirname(progname);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    (void) snprintf(lslib, sizeof(lslib), "%s/" LOCALLSLIB, progdir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (!(libpath = realpath(lslib, lsreal))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      fprintf(stderr, "Unable to resolve library path '%s': %s\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+              lslib, strerror(errno));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!(libhandle = dlopen(libpath, RTLD_FIRST))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(stderr, "Unable to open library: %s\n", dlerror());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (verbose) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("    Loaded %s, handle = 0x%0*lX\n", libpath,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           (int) sizeof(void *) * 2, UL libhandle);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return libhandle;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+close_lib(void **libhandle)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (*libhandle && dlclose(*libhandle)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(stderr, "Unable to close library: %s\n", dlerror());
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  *libhandle = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+clock_lookup(const char *name, void **handlep)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  void *adr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  /* Try extra library first, then general */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (*handlep && (adr = dlsym(*handlep, name))) return adr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  *handlep = RTLD_NEXT;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return dlsym(RTLD_NEXT, name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static const char *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+clock_find(clock_info_t *ci, void *libhandle, int verbose)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  const char *name = clock_func_names[ci->idx];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  void *func;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!(func = clock_lookup(name, &libhandle))) return name;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  switch (ci->type) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #define CLOCK_TYPE(name,valtyp) case clock_type_##name: \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      ci->f.name = func; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      CLOCK_TYPES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #undef CLOCK_TYPE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (verbose) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (libhandle == RTLD_NEXT) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("    Located %s in library handle RTLD_NEXT\n", name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("    Located %s in library handle 0x%0*lX\n", name,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             (int) sizeof(void *) * 2, UL libhandle);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+clock_alloc(clock_info_t *ci)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  void *bufp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int err;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  switch (ci->type) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #define CLOCK_TYPE(name,valtyp) case clock_type_##name: \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      bufp = ci->b.name = calloc(sizeof(valtyp), ci->numdiffs + 1); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      ci->be.name = bufp ? ci->b.name + ci->numdiffs : NULL; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      CLOCK_TYPES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #undef CLOCK_TYPE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!bufp) return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!(ci->nsbuf = calloc(sizeof(ns_time_t), ci->numdiffs + 1))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    err = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    free(bufp);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    errno = err;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ci->nsbufe = ci->nsbuf + ci->numdiffs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!(ci->hbuf = calloc(sizeof(histent_t), ci->numdiffs))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    err = errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    free(ci->nsbuf);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    free(bufp);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    errno = err;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+clock_free(clock_info_t *ci)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  void *bufp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  switch (ci->type) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #define CLOCK_TYPE(name,valtyp) case clock_type_##name: \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      bufp = ci->b.name; ci->b.name = ci->be.name = NULL; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      CLOCK_TYPES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #undef CLOCK_TYPE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  free(ci->hbuf); ci->hbuf = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  free(ci->nsbuf); ci->nsbuf = ci->nsbufe = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  free(bufp);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Universal collector/converter function */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+clock_collect(clock_info_t *ci)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_funcp_t funcp = ci->f;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clockid_t clkid = ci->clkid;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_bufp_t bufp = ci->b, cbufp = ci->b;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_bufp_t bufe = ci->be;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ns_time_t *nbp = ci->nsbuf;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  usleepx(ci->sleepus);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #define CLOCK_CALL_mach(type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    time_scratch.mach = (*funcp.type)(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (bufp.type <= bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *bufp.type++ = (*funcp.type)(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (cbufp.type <= bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *nbp++ = mt2nsec(*cbufp.type++); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #define CLOCK_CALL_timeofday(type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    (void) (*funcp.type)(bufp.type, NULL); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (bufp.type <= bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if ((ret = (*funcp.type)(bufp.type++, NULL))) return ret; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (cbufp.type <= bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *nbp++ = tv2nsec(cbufp.type++); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #define CLOCK_CALL_gettime(type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    (void) (*funcp.type)(clkid, bufp.type); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (bufp.type <= bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if ((ret = (*funcp.type)(clkid, bufp.type++))) return ret; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (cbufp.type <= bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *nbp++ = ts2nsec(cbufp.type++); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #define CLOCK_CALL_gettime_ns(type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    time_scratch.ns_time = (*funcp.type)(clkid); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (bufp.type <= bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (!(*bufp.type++ = (*funcp.type)(clkid))) return -1; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (cbufp.type <= bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *nbp++ = *cbufp.type++; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  switch (ci->type) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #define CLOCK_TYPE(name,valtyp) case clock_type_##name: \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      CALLMAC(CLOCK_CALL_,name,name)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      CLOCK_TYPES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #undef CLOCK_TYPE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #undef CLOCK_CALL_timeofday
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #undef CLOCK_CALL_mach
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #undef CLOCK_CALL_gettime
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #undef CLOCK_CALL_gettime_ns
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Universal compare collector/converter function */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+clock_compare(clock_info_t *ci, clock_info_t *rci)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_funcp_t funcp = ci->f;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clockid_t clkid = ci->clkid;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_bufp_t bufp = ci->b, cbufp = ci->b;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_bufp_t bufe = ci->be;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ns_time_t *nbp = ci->nsbuf;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  mach_time_t *mtrp = rci->b.mach, *rmtrp = rci->b.mach;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  mach_time_t *mtpe = rci->be.mach;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ns_time_t *rnbp = rci->nsbuf;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  assert(rci->idx == clock_idx_mach_absolute && "Unexpected reference clock");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  usleepx(ci->sleepus);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #define CLOCK_CALL_mach(type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    time_scratch.mach = mach_absolute_time(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    time_scratch.mach = (*funcp.type)(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    *mtrp++ = mach_absolute_time(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (bufp.type < bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *bufp.type++ = (*funcp.type)(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *mtrp++ = mach_absolute_time(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (cbufp.type < bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *nbp++ = mt2nsec(*cbufp.type++); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #define CLOCK_CALL_timeofday(type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    time_scratch.mach = mach_absolute_time(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    (void) (*funcp.type)(bufp.type, NULL); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    *mtrp++ = mach_absolute_time(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (bufp.type < bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if ((ret = (*funcp.type)(bufp.type++, NULL))) return ret; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *mtrp++ = mach_absolute_time(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (cbufp.type < bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *nbp++ = tv2nsec(cbufp.type++); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #define CLOCK_CALL_gettime(type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    time_scratch.mach = mach_absolute_time(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    (void) (*funcp.type)(clkid, bufp.type); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    *mtrp++ = mach_absolute_time(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (bufp.type < bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if ((ret = (*funcp.type)(clkid, bufp.type++))) return ret; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *mtrp++ = mach_absolute_time(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (cbufp.type < bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *nbp++ = ts2nsec(cbufp.type++); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #define CLOCK_CALL_gettime_ns(type) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    time_scratch.mach = mach_absolute_time(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    time_scratch.ns_time = (*funcp.type)(clkid); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    *mtrp++ = mach_absolute_time(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (bufp.type < bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (!(*bufp.type++ = (*funcp.type)(clkid))) return -1; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *mtrp++ = mach_absolute_time(); \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while (cbufp.type < bufe.type) { \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *nbp++ = *cbufp.type++; \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  switch (ci->type) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #define CLOCK_TYPE(name,valtyp) case clock_type_##name: \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      CALLMAC(CLOCK_CALL_,name,name)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      CLOCK_TYPES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    #undef CLOCK_TYPE
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #undef CLOCK_CALL_timeofday
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #undef CLOCK_CALL_mach
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #undef CLOCK_CALL_gettime
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  #undef CLOCK_CALL_gettime_ns
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  while (rmtrp <= mtpe) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    *rnbp++ = mt2nsec(*rmtrp++);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Dump all clock samples */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+clock_dump_ns(clock_info_t *ci, int quiet)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int index;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ns_time_t cur;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  sns_time_t last = quiet > 2 ? ci->nsbuf[0] : -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!quiet) printf("Samples of '%s':\n", clock_names[ci->idx]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  for (index = 0; index <= ci->numdiffs; ++index) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    cur = ci->nsbuf[index];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (quiet > 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("%7d %llu %4d\n", index, ULL cur, (int) (cur - last));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else if (last < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("%7d: %llu\n", index, ULL cur);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("%7d: %llu (%d)\n", index, ULL cur, (int) (cur - last));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    last = cur;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Dump all interleaved samples */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+clock_dump_dual_ns(clock_info_t *ci, clock_info_t *rci, int quiet)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int numdiffs = ci->numdiffs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  mach_time_t *rmp = rci->b.mach;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  sns_time_t ref_mean, tst_mean, mean_diff;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int index;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ns_time_t cur, next, tstcur;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  sns_time_t last = quiet > 2 ? rci->nsbuf[0] : -1, mean, diff;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ref_mean = mt2nsec(rmp[0] + rmp[1] + rmp[numdiffs-1] + rmp[numdiffs]) / 4;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  tst_mean = (ci->nsbuf[0] + ci->nsbuf[numdiffs-1]) / 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  mean_diff = tst_mean - ref_mean;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!quiet) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("Samples (ns) of '%s', interleaved with '%s':\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           clock_names[ci->idx], clock_names[rci->idx]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("  Ref mean = %lld, Test mean = %lld, Diff = %lld\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           LL ref_mean, LL tst_mean, LL mean_diff);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  for (index = 0; index < numdiffs; ++index) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    cur = rci->nsbuf[index];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (quiet <= 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (last < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        printf("%7d: %llu\n", index, ULL cur);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        printf("%7d: %llu (%d)\n", index, ULL cur, (int) (cur - last));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    next = rci->nsbuf[index+1];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    mean = (cur + next) / 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    tstcur = ci->nsbuf[index];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    diff = tstcur - mean;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (quiet <= 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("         %llu (%lld +mean_diff %+lld)\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             ULL tstcur, LL mean, LL (diff - mean_diff));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("%7d %llu %4d %llu %lld %+4lld\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             index, ULL cur, (int) (cur - last),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+             ULL tstcur, LL mean, LL (diff - mean_diff));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    last = cur;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  cur = rci->nsbuf[index];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  printf(quiet <= 2 ? "%7d: %llu (%d)\n" : "%7d %llu %4d\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+         index, ULL cur, (int) (cur - last));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Generate deltas for histogram */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+gen_deltas(clock_info_t *ci)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ns_time_t *nsp = ci->nsbuf;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  histent_t *hp = ci->hbuf;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  sns_time_t last, cur;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  last = *nsp++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  while (nsp <= ci->nsbufe) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    cur = *nsp++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    hp->diff = cur - last; hp++->count = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    last = cur;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Generate offsets for histogram */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+gen_offsets(clock_info_t *ci, clock_info_t *rci)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int numdiffs = ci->numdiffs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  mach_time_t *rmp = rci->b.mach;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  sns_time_t ref_mean, tst_mean;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int index;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ns_time_t cur, next, tstcur;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  sns_time_t last = -1, mean, diff;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  histent_t *hp = ci->hbuf;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ref_mean = mt2nsec(rmp[0] + rmp[1] + rmp[numdiffs-1] + rmp[numdiffs]) / 4;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  tst_mean = (ci->nsbuf[0] + ci->nsbuf[numdiffs-1]) / 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ci->mean_diff = tst_mean - ref_mean;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  for (index = 0; index < numdiffs; ++index) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    cur = rci->nsbuf[index];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    next = rci->nsbuf[index+1];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    mean = (cur + next) / 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    tstcur = ci->nsbuf[index];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    diff = tstcur - mean;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    hp->diff = diff - ci->mean_diff; hp++->count = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    last = cur;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Sort deltas */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+hcomp_diff(const void *h1v, const void *h2v)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  const histent_t *h1 = (const histent_t *) h1v;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  const histent_t *h2 = (const histent_t *) h2v;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (h1->diff == h2->diff) return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return h1->diff < h2->diff ? -1 : 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+hsort_diff(clock_info_t *ci)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  qsort(ci->hbuf, ci->numdiffs, sizeof(histent_t), hcomp_diff);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Compress runs of identical diffs */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+hcoll_diff(clock_info_t *ci)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  histent_t *hpi = ci->hbuf, *hpo = ci->hbuf;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  histent_t *hpe = ci->hbuf + ci->numdiffs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  while (hpi < hpe) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (hpi->diff == hpo->diff) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      ++hpo->count; ++hpi;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      *++hpo = *hpi;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  ci->hbufe = hpo + 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Generate histogram */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+gen_hist(clock_info_t *ci)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  gen_deltas(ci);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  hsort_diff(ci);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  hcoll_diff(ci);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Generate comparison histogram */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+gen_hist2(clock_info_t *ci, clock_info_t *rci)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  gen_offsets(ci, rci);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  hsort_diff(ci);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  hcoll_diff(ci);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Print histogram */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+dump_hist(clock_info_t *ci, int diffmode, int quiet)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  const histent_t *hp = ci->hbuf;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  const char *type = diffmode ? "diff" : "delta";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!quiet) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("Histogram of ns %ss for '%s' (%s: count):\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           type, clock_names[ci->idx], type);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  while (hp < ci->hbufe) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("%5d: %5d\n", (int) hp->diff, (int) hp->count);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ++hp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Print dual histogram */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+dump_hist2(clock_info_t *ci, clock_info_t *rci, int quiet)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  const histent_t *hp = ci->hbuf, *rhp = rci->hbuf;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!quiet) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("Histograms of ns diffs/deltas for '%s' vs '%s' (val: count)\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           clock_names[ci->idx], clock_names[rci->idx]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("  Diffs are relative to mean diff %lld\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           LL ci->mean_diff);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  while (hp < ci->hbufe && rhp < rci->hbufe) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("%7d: %5d        %7d: %5d\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           (int) hp->diff, (int) hp->count, (int) rhp->diff, (int) rhp->count);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ++hp; ++rhp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  while (hp < ci->hbufe) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("%7d: %5d\n", (int) hp->diff, (int) hp->count);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ++hp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  while (rhp < rci->hbufe) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("                      %7d: %5d\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+           (int) rhp->diff, (int) rhp->count);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ++rhp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static long
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+getnum(const char *arg, const char *name, long minval, long maxval)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  long val;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char *cp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  val = strtol(arg, &cp, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (*cp) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(stderr, "Bad %s argument.\n", name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    exit(20);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (val < minval || val > maxval) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fprintf(stderr, "Value %ld for %s out of range [%ld:%ld].\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+            val, name, minval, maxval);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    exit(20);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return val;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+usage(FILE *fp, const char *name)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  fprintf(fp, "Usage is: %s [<opts>] [<clock> [<num diffs> [<sleep ms>]]]\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+          name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  fprintf(fp, "  Options:\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  fprintf(fp, "    -c:  Compare clock against mach_absolute_time\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  fprintf(fp, "    -h:  This text\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  fprintf(fp, "    -l:  List available clocks in this system\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  fprintf(fp, "    -L:  List defined clocks\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  fprintf(fp, "    -q:  Quiet (suppress headers)\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  fprintf(fp, "    -v:  Verbose output\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  fprintf(fp, "    -y:  Load system legacy-support library\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  fprintf(fp, "    -Y:  Load build-tree legacy-support library\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+list_clocks(int all, void *libhandle, int quiet)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  const char *cname, *fname;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_idx_t clockidx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  void *handle;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!quiet) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("%s clock names:\n", all ? "Defined" : "Available");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  while (1) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    fname = clock_func_names[clockidx];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (!(cname = clock_names[clockidx++])) break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (!all) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      handle = libhandle;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (!clock_lookup(fname, &handle)) continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    printf("  %s\n", cname);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+main(int argc, char *argv[])
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int argn = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int compare = 0, help = 0, list = 0, quiet = 0, verbose = 0, legacy = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int err = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  const char *cp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char chr;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_idx_t clockidx = DEF_CLOCK_IDX;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  char *name = basename(argv[0]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  void *libhandle = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  const char *clock_name = NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  long numdiffs = DEF_NUM_DIFFS, sleepms = DEF_SLEEP_MS;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_info_t tci = {0}, rci = {0};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  while (argn < argc && argv[argn][0] == '-') {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    cp = argv[argn];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while ((chr = *++cp)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      switch (chr) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        case 'c': compare = 1; break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        case 'h': help = 1; break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        case 'l': list = 1; break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        case 'L': list = -1; break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        case 'q': ++quiet; break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        case 'v': ++verbose; break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        case 'y': legacy = 1; break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        case 'Y': legacy = -1; break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ++argn;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (argn < argc) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    clock_name = argv[argn];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ++argn;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (argn < argc) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    numdiffs = getnum(argv[argn], "num_diffs", MIN_DIFFS, MAX_DIFFS);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ++argn;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (argn < argc) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    sleepms = getnum(argv[argn], "sleep (ms)", MIN_SLEEP, MAX_SLEEP);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    ++argn;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (help) usage(stdout, name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (list < 0) list_clocks(1, NULL, quiet);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if ((help && !list) || list < 0 ) return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (legacy) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (!(libhandle = load_lib(legacy, argv[0], verbose && !quiet))) return 10;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (list > 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    list_clocks(0, libhandle, quiet);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (clock_name && strcmp(clock_name, ".")) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    clockidx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    while ((cp = clock_names[clockidx])) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (!strcmp(clock_name, cp)) break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      ++clockidx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (!cp) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      fprintf(stderr, "Unrecognized clock name '%s'\n", clock_name);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      return 20;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  setup_info(&tci, clockidx, numdiffs, sleepms);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  setup_info(&rci, REF_CLOCK_IDX, numdiffs, sleepms);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  do {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if ((err = setup_mach(verbose && !quiet))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      perror("Unable to get mach time scale");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if ((cp = clock_find(&tci, libhandle, verbose && !quiet))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      fprintf(stderr, "Function '%s' is unavailable\n", cp);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      err = 10; break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (compare && (cp = clock_find(&rci, libhandle, verbose && !quiet))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      fprintf(stderr, "Function '%s' is unavailable\n", cp);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      err = 10; break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if ((err = clock_alloc(&tci))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      perror("Unable to allocate sample buffers");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (compare && (err = clock_alloc(&rci))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      perror("Unable to allocate reference buffers");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (!compare) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if ((err = clock_collect(&tci))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        perror("Clock collection failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (verbose >= 2) clock_dump_ns(&tci, quiet);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      gen_hist(&tci);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (quiet < 2) dump_hist(&tci, 0, quiet);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if ((err = clock_compare(&tci, &rci))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        perror("Clock compare collection failed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (verbose >= 2) clock_dump_dual_ns(&tci, &rci, quiet);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      gen_hist(&rci);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      gen_hist2(&tci, &rci);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (quiet < 2) dump_hist2(&tci, &rci, quiet);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  } while (0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_free(&rci);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  clock_free(&tci);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  close_lib(&libhandle);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (!quiet) printf("%s %s.\n", name, err ? "failed" : "completed");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  return err;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span></pre><pre style='margin:0'>

</pre>