<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/ef3531a4875525796800c4a5137fec8f66a8ac9e">https://github.com/macports/macports-legacy-support/commit/ef3531a4875525796800c4a5137fec8f66a8ac9e</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit ef3531a4875525796800c4a5137fec8f66a8ac9e
</span>Author: Fred Wright <fw@fwright.net>
AuthorDate: Fri Apr 11 16:43:39 2025 -0700
<span style='display:block; white-space:pre;color:#404040;'> test_clocks: Add cross-check tests.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> This checks for the relationships between various clocks and
</span><span style='display:block; white-space:pre;color:#404040;'> mach_absolute_time.
</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;'> Passes and provides plausible info on all platforms, with both old and
</span><span style='display:block; white-space:pre;color:#404040;'> new clock implementations.
</span>---
test/test_clocks.c | 189 +++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 141 insertions(+), 48 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/test/test_clocks.c b/test/test_clocks.c
</span><span style='display:block; white-space:pre;color:#808080;'>index c87032d..58cd4af 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/test/test_clocks.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/test/test_clocks.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -65,7 +65,6 @@ typedef int64_t sns_time_t;
</span> #define MILLION 1000000U
#define BILLION 1000000000U
#define BILLION64 1000000000ULL
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#define BILLIONDBL 1000000000.0
</span>
/* Parameters for collection sequence */
#define MAX_STEP_NS 700000 /* Maximum delta not considered a step */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -73,13 +72,17 @@ typedef int64_t sns_time_t;
</span> #define STD_SLEEP_US 1000 /* Standard sleep before collecting */
#define MAX_SLEEP_US 100000 /* Maximum sleep when retrying */
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifndef TEST_TEMP
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define TEST_TEMP "/dev/null"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> #define LL (long long)
#define ULL (unsigned long long)
typedef unsigned long pointer_int_t;
static mach_timebase_info_data_t tbinfo;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-static long double mach2nanos, mach2usecs, mach2secs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static long double mach2nanos, mach2usecs;
</span> static ns_time_t mach_res;
/* Bit bucket for cache warmup calls */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -102,6 +105,8 @@ static volatile union scratch_u {
</span> ONE_ERROR(zerostep,"Too many consecutive unchanged samples") \
ONE_ERROR(step,"Too many retries to avoid step") \
ONE_ERROR(noerrno,"Error with errno not set") \
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ ONE_ERROR(early,"Test clock too early") \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ONE_ERROR(late,"Test clock too late") \
</span>
#define ONE_ERROR(name,text) err_##name,
typedef enum errs { err_dummy, /* Avoid zero */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -175,7 +180,6 @@ typedef enum clock_type {
</span> NP_CLOCK(UPTIME_RAW_APPROX,type,0,0,1) \
#define CALLMAC(a,b,c) a##b(c)
<span style='display:block; white-space:pre;background:#ffe0e0;'>-#define CONC(a,b) a##b
</span>
/* Clock type codes */
#define CLOCK_IDX_timeofday(name) clock_idx_##name
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -226,6 +230,12 @@ static const int clock_okstep[] = {
</span> };
#undef NP_CLOCK
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#define NP_CLOCK(name,type,okstep,okadj,approx) okadj,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static const int clock_okadj[] = {
</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> #define NP_CLOCK(name,type,okstep,okadj,approx) approx,
static const int clock_approx[] = {
NP_CLOCKS
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -286,14 +296,19 @@ typedef struct dstats_s {
</span> double sqmean;
} dstats_t;
<span style='display:block; white-space:pre;background:#ffe0e0;'>-/* Struct for info on clock errors */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Struct for info on (possible) clock errors */
</span> typedef struct errinfo_s {
ns_time_t first;
ns_time_t last;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ sns_time_t difflim;
</span> int index;
ns_time_t prev;
ns_time_t cur;
ns_time_t nzmin;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ sns_time_t lastmin;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ sns_time_t lastmax;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ sns_time_t curmin;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ sns_time_t curmax;
</span> int badsame;
int maxsame;
int retries;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -336,7 +351,6 @@ setup(int verbose)
</span> }
mach2nanos = (long double) tbinfo.numer / tbinfo.denom;
mach2usecs = mach2nanos / 1000.0;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- mach2secs = mach2nanos / BILLIONDBL;
</span> mach_res = (tbinfo.numer + tbinfo.denom - 1) / tbinfo.denom;
if (verbose) {
printf(" Scale for mach_time (nanoseconds per unit) is %u/%u = %.3f\n",
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -718,6 +732,8 @@ report_clock_err(clock_idx_t clkidx, const errinfo_t *ei,
</span> ULL ei->first, ULL ei->last, ei->index,
ULL ei->prev, ULL ei->cur, ULL (ei->cur - ei->prev),
ei->badsame, ei->maxsame, ei->retries);
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ printf(" last min/max = %lld/%lld, cur min/max = %lld/%lld\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ LL ei->lastmin, LL ei->lastmax, LL ei->curmin, LL ei->curmax);
</span> }
}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1008,40 +1024,86 @@ sandwich_samples(clock_idx_t clkidx, errinfo_t *ei)
</span> return ret;
}
<span style='display:block; white-space:pre;background:#ffe0e0;'>-/* Get and check one clock and reference */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Check test clock against reference.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * In general there is a potentially large offset between the two clocks,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * but we check the offset behavior for consistency. The general idea is
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * to compute minimum and maximum differences, based on the previous and
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * subsequent reference values, adjusted by a tolerance value. The behavior
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * is considered correct when each min/max interval overlaps the preceding
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * min/max interval.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Steerable clocks complicate this. Not only do explicit step adjustments
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * (which are mostly but not completely filtered out earlier) violate this
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * criterion, but even "slewing" adjustments involve periodic small step
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * adjustments which break things as well. To allow for this, we make
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * the overlap failure a retriable error on steerable clocks; otherwise
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * it's fatal.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * In principle, at most one such step should be allowed within a given
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * sample set, but we don't bother to check for that.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * A similar issue exists with approximate clocks, which stay at the same
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * value for a long time and then jump. While it might be possible to
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * come up with a more finely-tuned exception for those, for simplicity
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * we just give them a treatment similar to steerable clocks, except for
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * limiting it to the "late" case.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span> static int
<span style='display:block; white-space:pre;background:#ffe0e0;'>-check_clock_sandwich(clock_idx_t clkidx, errinfo_t *ei, errinfo_t *eir)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+compare_clocks(clock_idx_t clkidx, errinfo_t *ei, errinfo_t *eir, dstats_t *dp)
</span> {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- int ret, tries = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- useconds_t sleepus = STD_SLEEP_US;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ const ns_time_t *refbp = &refnsbuf[0];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ const ns_time_t *testbp = nsbufp[clock_types[clkidx]];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ const ns_time_t *refp = refbp, *testp = testbp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ sns_time_t last, cur, tstcur = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int ret = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ sns_time_t minref = 0, maxref = 0, difflim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ sns_time_t lastmin = INT64_MIN, lastmax = INT64_MAX, curmin = 0, curmax = 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;'>+ * The maximum discrepancy between clocks (after accounting for the offset)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * is the sum of the resolutions of the clocks. But since the resolution
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * is reported overoptimistically on some platforms (x86), we use the larger
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * of the reported resolution and the observed minimum nonzero difference.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ difflim = MAX(clock_res[clkidx], ei->nzmin)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ + MAX(clock_res[clock_idx_mach_absolute], eir->nzmin);
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>- do {
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ei->errnum = eir->errnum = errno = 0;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- usleepx(sleepus);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if ((ret = sandwich_samples(clkidx, ei))) break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- sleepus = MIN(sleepus * 2, MAX_SLEEP_US);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ last = *refp++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ while (testp < &testbp[NUM_DIFFS]) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ tstcur = *testp++; cur = *refp++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ minref = last - difflim; maxref = cur + difflim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ curmin = tstcur - maxref; curmax = tstcur - minref;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (curmax < lastmin || curmin > lastmax) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ei->errnum = curmax < lastmin ? -err_early : -err_late;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = clock_okadj[clkidx]
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ || (clock_approx[clkidx] && curmin > lastmax) ? 1 : -1;
</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;'>+ last = cur; lastmin = curmin; lastmax = curmax;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>- ret = check_samples(clock_idx_mach_absolute, refnsbuf, 0, eir);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if (ret) { if (ret < 0) break; continue; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ei->first = testbp[0]; ei->last = testbp[NUM_DIFFS - 1];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ei->difflim = difflim;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ei->index = ret ? testp - testbp - 1 : -2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ei->prev = ei->cur = tstcur;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ei->lastmin = lastmin; ei->lastmax = lastmax;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ei->curmin = curmin; ei->curmax = curmax;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ei->retries = -1;
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>- ret = check_samples(clkidx, nsbufp[clock_types[clkidx]], 1, ei);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if (ret <= 0) break;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- } while (++tries < MAX_STEP_TRIES);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- ei->retries = eir->retries = tries;
</span> return ret;
}
<span style='display:block; white-space:pre;background:#ffe0e0;'>-/* Compare clocks */
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-static int
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-compare_clocks(clock_idx_t clkidx, dstats_t *dp)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Get stats on comparison */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+get_dstats(clock_idx_t clkidx, dstats_t *dp)
</span> {
const ns_time_t *refbp = &refnsbuf[0];
const ns_time_t *testbp = nsbufp[clock_types[clkidx]];
const ns_time_t *refp = refbp, *testp = testbp;
sns_time_t last, cur, mean, tstcur, expected;
sns_time_t refofs, diff;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- int numdiffs = 0;
</span> long double slope, diffsqr, difftot;
/* Use mean values of straddling reference pairs as comparison reference */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1058,19 +1120,44 @@ compare_clocks(clock_idx_t clkidx, dstats_t *dp)
</span>
last = *refp++;
while (testp < &testbp[NUM_DIFFS]) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- tstcur = *testp++; cur = *refp++; mean = (last + cur) / 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- last = cur;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ tstcur = *testp++; cur = *refp++;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ mean = (last + cur) / 2;
</span> refofs = mean - (sns_time_t) dp->refmean;
expected = (sns_time_t) (refofs * slope) + dp->testmean;
diff = tstcur - expected; diffsqr = (long double) diff * diff;
if (diffsqr < dp->sqmin) dp->sqmin = diffsqr;
if (diffsqr > dp->sqmax) dp->sqmax = diffsqr;
difftot += diffsqr;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- ++numdiffs;
</span> }
<span style='display:block; white-space:pre;background:#ffe0e0;'>- dp->sqmean = difftot / numdiffs;
</span>
<span style='display:block; white-space:pre;background:#ffe0e0;'>- return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ dp->sqmean = difftot / NUM_DIFFS;
</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;'>+/* Get and check one clock and reference */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+check_clock_sandwich(clock_idx_t clkidx,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ errinfo_t *ei, errinfo_t *eir, dstats_t *dp)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int ret, tries = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ useconds_t sleepus = STD_SLEEP_US;
</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;'>+ ei->errnum = eir->errnum = errno = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ usleepx(sleepus);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((ret = sandwich_samples(clkidx, ei))) break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ sleepus = MIN(sleepus * 2, MAX_SLEEP_US);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = check_samples(clock_idx_mach_absolute, refnsbuf, 0, eir);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (ret) { if (ret < 0) break; continue; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = check_samples(clkidx, nsbufp[clock_types[clkidx]], 1, ei);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (ret) { if (ret < 0) break; continue; }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = compare_clocks(clkidx, ei, eir, dp);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (ret <= 0) break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } while (++tries < MAX_STEP_TRIES);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ei->retries = eir->retries = tries;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ret;
</span> }
/* Print comparison stats */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1098,15 +1185,11 @@ clock_dump_dual_ns(clock_idx_t clkidx, errinfo_t *ei, errinfo_t *eir,
</span> int verbose, int quiet)
{
int idx;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- mach_time_t *rmp = refbuf;
</span> ns_time_t cur, next, tstcur, *nsbuf = nsbufp[clock_types[clkidx]];
<span style='display:block; white-space:pre;background:#ffe0e0;'>- sns_time_t last = refnsbuf[0], mean, diff;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- sns_time_t ref_mean, tst_mean, mean_diff;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ sns_time_t last = refnsbuf[0], meanofs, tstmin, tstmax, mean, diff;
</span> FILE *fp;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- ref_mean = mt2nsec(rmp[0] + rmp[1] + rmp[NUM_DIFFS-1] + rmp[NUM_DIFFS]) / 4;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- tst_mean = (nsbuf[0] + nsbuf[NUM_DIFFS-1]) / 2;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- mean_diff = tst_mean - ref_mean;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ meanofs = (sns_time_t) (ei->first + ei->last - eir->first - eir->last) / 2;
</span>
if (!(fp = open_log(clkidx, "-vs-mach", quiet))) return;
if (verbose >= 2) {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1116,14 +1199,16 @@ clock_dump_dual_ns(clock_idx_t clkidx, errinfo_t *ei, errinfo_t *eir,
</span> fprintf(fp, "# Nonzero min ref delta = %d, min test delta = %d,"
" max consecutive same = %d\n",
(int) eir->nzmin, (int) ei->nzmin, ei->badsame);
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(fp, "# Average time per sample = %.1f ns, diff tolerance = %lld,"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ " retries = %d\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ (double) (ei->last - ei->first) / (NUM_DIFFS - 1),
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ LL ei->difflim, ei->retries);
</span> fprintf(fp, "# First ref value = %llu, last = %llu, diff = %llu\n",
ULL eir->first, ULL eir->last, ULL (eir->last - eir->first));
fprintf(fp, "# First test value = %llu, last = %llu, diff = %llu\n",
ULL ei->first, ULL ei->last, ULL (ei->last - ei->first));
<span style='display:block; white-space:pre;background:#ffe0e0;'>- fprintf(fp, "# Average time per sample = %.1f ns, retries = %d\n",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- (double) (ei->last - ei->first) / (NUM_DIFFS - 1), ei->retries);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- fprintf(fp, "# Mean ref = %lld, mean test = %lld, diff = %lld\n",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- LL ref_mean, LL tst_mean, LL mean_diff);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(fp, "# Mean diff = %lld (subtracted from Diff, Rmin, Rmax)\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ LL meanofs);
</span> if (eir->errnum) {
fprintf(fp, "#\n");
fprintf(fp, "# *** Reference Clock Error %d (%s)\n",
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1138,20 +1223,26 @@ clock_dump_dual_ns(clock_idx_t clkidx, errinfo_t *ei, errinfo_t *eir,
</span> ei->errnum, get_errstr(ei->errnum));
fprintf(fp, "# *** Failed @%d: %llu\n",
ei->index, ULL ei->cur);
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(fp, "# *** Last min/max = %lld/%lld\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ LL ei->lastmin, LL ei->lastmax);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(fp, "# *** Current min/max = %lld/%lld\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ LL ei->curmin, LL ei->curmax);
</span> }
fprintf(fp, "#\n");
}
if (verbose) fprintf(fp, "# Index Reference Delta"
<span style='display:block; white-space:pre;background:#ffe0e0;'>- " Test_Value Adj_Ref_Mean Ofs\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ " Test_Value Diff"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ " Rmin Rmax\n");
</span> for (idx = 0; idx < NUM_DIFFS; ++idx) {
cur = refnsbuf[idx];
next = refnsbuf[idx+1];
<span style='display:block; white-space:pre;background:#ffe0e0;'>- mean = (cur + next) / 2 + mean_diff;
</span> tstcur = nsbuf[idx];
<span style='display:block; white-space:pre;background:#ffe0e0;'>- diff = tstcur - mean;
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- fprintf(fp, "%7d %19llu %5d %19llu %+20lld %+5lld\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ mean = (cur + next) / 2; diff = (sns_time_t) tstcur - mean - meanofs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ tstmin = tstcur - (next + ei->difflim);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ tstmax = tstcur - (cur - ei->difflim);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(fp, "%7d %19llu %5d %19llu %+5lld %+5lld %+5lld\n",
</span> idx, ULL cur, (int) (cur - last),
<span style='display:block; white-space:pre;background:#ffe0e0;'>- ULL tstcur, LL mean, LL diff);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ULL tstcur, LL diff, LL tstmin - meanofs, LL tstmax - meanofs);
</span> last = cur;
}
cur = refnsbuf[idx];
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1171,7 +1262,7 @@ report_clock_compare(clock_idx_t clkidx, int dump, int verbose, int quiet)
</span>
if (vnq) printf(" Comparing %s to mach_absolute_time\n", name);
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if (check_clock_sandwich(clkidx, &info, &refinfo)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (check_clock_sandwich(clkidx, &info, &refinfo, &dstats)) {
</span> if (refinfo.errnum) {
report_clock_err(clock_idx_mach_absolute, &refinfo, 0, verbose);
}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1180,8 +1271,10 @@ report_clock_compare(clock_idx_t clkidx, int dump, int verbose, int quiet)
</span> }
ret = 1;
} else {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- ret |= compare_clocks(clkidx, &dstats);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if (vnq & !ret) print_dstats(clkidx, &dstats);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (vnq) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ get_dstats(clkidx, &dstats);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ print_dstats(clkidx, &dstats);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> }
if ((dump && ret) || dump > 1) {
clock_dump_dual_ns(clkidx, &info, &refinfo, verbose, quiet);
</pre><pre style='margin:0'>
</pre>