<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/9a097faffab391c34de7a039d6251234c7b67df7">https://github.com/macports/macports-legacy-support/commit/9a097faffab391c34de7a039d6251234c7b67df7</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 9a097faffab391c34de7a039d6251234c7b67df7
</span>Author: Fred Wright <fw@fwright.net>
AuthorDate: Mon May 5 22:36:20 2025 -0700
<span style='display:block; white-space:pre;color:#404040;'> test_clocks: Implement replay feature.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> This allows previously captured logs (not necessarily on the same
</span><span style='display:block; white-space:pre;color:#404040;'> system) to be replayed for the tests, to facilitate debugging and
</span><span style='display:block; white-space:pre;color:#404040;'> testing.
</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.
</span>---
test/test_clocks.c | 178 ++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 150 insertions(+), 28 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 998076b..a19139b 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;'>@@ -22,6 +22,19 @@
</span> * calculations may be done in floating-point, but its range may not be
* sufficient for absolute (1970-relative) values in nanoseconds. We sometimes
* use long doubles, but they're not always better than doubles.
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Since clock values are inherently nonreproducible, the challenge in clock
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * tests is to have criteria which are tight enough to detect genuine problems,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * while being loose enough to tolerate normal variations. In many cases, we
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * rely on retries for the latter aspect.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * To facilitate debugging, we provide both a means to capture clock samples
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * into logfiles (either conditionally on errors or unconditionally), and a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * means to replay previously captured logs into the tests. Note that certain
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * parameters, such as the mach_time scale and the clock resolutions, are not
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * captured in the logfiles, so it's assumed that values from the current
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * system are acceptable. Since the replayed clocks are always the nanosecond
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * versions, matching the mach_time scale is unimportant.
</span> */
#include <errno.h>
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -88,7 +101,9 @@ typedef int64_t sns_time_t;
</span> #endif
#define LL (long long)
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#define LLP (long long *)
</span> #define ULL (unsigned long long)
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#define ULLP (unsigned long long *)
</span>
typedef unsigned long pointer_int_t;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -686,26 +701,34 @@ get_stats(clock_idx_t clkidx, cstats_t *sp)
</span> if (!diff) {
if (++cursame > sp->maxsame) sp->maxsame = cursame;
} else {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- cursame =0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ cursame = 0;
</span> }
}
sp->stddev = sqrt(sqsum / (NUM_DIFFS - 1));
}
/* Get and check one clock */
<span style='display:block; white-space:pre;background:#e0ffe0;'>+static int clock_replay_ns(clock_idx_t clkidx, int quiet);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> static int
<span style='display:block; white-space:pre;background:#ffe0e0;'>-check_clock(clock_idx_t clkidx, cstats_t *sp, errinfo_t *ei)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+check_clock(clock_idx_t clkidx, cstats_t *sp, errinfo_t *ei,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int quiet, int replay)
</span> {
int ret, tries = 0;
useconds_t sleepus = STD_SLEEP_US;
do {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- usleepx(sleepus);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- if ((ret = collect_samples(clkidx, ei))) break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!replay) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ usleepx(sleepus);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((ret = collect_samples(clkidx, ei))) break;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ei->retries = -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((ret = clock_replay_ns(clkidx, quiet))) return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> ret = check_samples(clkidx, nsbufp[clock_types[clkidx]], 0, ei);
if (ret <= 0) break;
sleepus = MIN(sleepus * 2, MAX_SLEEP_US);
<span style='display:block; white-space:pre;background:#ffe0e0;'>- } while (++tries < MAX_STEP_TRIES);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } while (!replay && ++tries < MAX_STEP_TRIES);
</span>
ei->retries = tries;
if (!ret && sp) get_stats(clkidx, sp);
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -760,7 +783,7 @@ print_stats(const cstats_t *sp, const errinfo_t *ei)
</span>
/* Open logfile for writing */
static FILE *
<span style='display:block; white-space:pre;background:#ffe0e0;'>-open_log(clock_idx_t clkidx, const char *extra, int quiet)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+open_log(clock_idx_t clkidx, const char *extra, int quiet, int replay)
</span> {
FILE *fp;
const char *name = clock_names[clkidx];
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -768,11 +791,16 @@ open_log(clock_idx_t clkidx, const char *extra, int quiet)
</span>
snprintf(fname, sizeof(fname), TEST_TEMP "/%s-%s%s.log",
progname, name, extra);
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if(!(fp = fopen(fname, "w"))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if(!(fp = fopen(fname, replay ? "r" : "w"))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (replay && errno == ENOENT) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!quiet) fprintf(stderr, " Skipping nonexistent %s\n", fname);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> fprintf(stderr, " Unable to open %s\n", fname);
return NULL;
}
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if (!quiet) printf(" Logging to " TEST_TEMP "/\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!quiet) printf(" %s %s/\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ replay ? "Replaying from" : "Logging to", fname);
</span> return fp;
}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -785,7 +813,7 @@ clock_dump_ns(clock_idx_t clkidx, errinfo_t *ei, int verbose, int quiet)
</span> sns_time_t last = nsbuf[0];
FILE *fp;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if (!(fp = open_log(clkidx, "", quiet))) return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!(fp = open_log(clkidx, "", quiet, 0))) return;
</span> if (verbose >= 2) {
fprintf(fp, "# Capture of %d %s samples (%s), retries = %d\n",
NUM_SAMPLES, clock_names[clkidx],
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -808,15 +836,53 @@ clock_dump_ns(clock_idx_t clkidx, errinfo_t *ei, int verbose, int quiet)
</span> if (verbose) fprintf(fp, "# Index Value Delta\n");
for (idx = 0; idx < NUM_SAMPLES; ++idx) {
cur = nsbuf[idx];
<span style='display:block; white-space:pre;background:#ffe0e0;'>- fprintf(fp, "%7d %19llu %5d\n", idx, ULL cur, (int) (cur - last));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(fp, " %6d %19llu %5d\n", idx, ULL cur, (int) (cur - last));
</span> last = cur;
}
fclose(fp);
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Replay data from prior dump */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+clock_replay_ns(clock_idx_t clkidx, int quiet)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int ret = 0, count, idx = -1, diff;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char pfx, eol, buf[256];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ns_time_t cur, *nsbuf = nsbufp[clock_types[clkidx]];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ FILE *fp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!(fp = open_log(clkidx, "", quiet, 1))) return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ do {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!fgets(buf, sizeof(buf), fp)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = !feof(fp);
</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;'>+ count = sscanf(buf, "%c%d %llu %d%c",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ &pfx, &idx, ULLP &cur, &diff, &eol);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (count < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = 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;'>+ if (pfx == '#') continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (pfx != ' ' || eol != '\n' || count != 5) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!quiet) fprintf(stderr, " Bad line at/after index %d\n", idx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = -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;'>+ if (idx < 0 || idx >= NUM_SAMPLES) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!quiet) fprintf(stderr, " Skipping bad index %d\n", idx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ nsbuf[idx] = cur;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } while (1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fclose(fp);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /* Report info about one clock */
static int
<span style='display:block; white-space:pre;background:#ffe0e0;'>-report_clock(clock_idx_t clkidx, int dump, int verbose, int quiet)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+report_clock(clock_idx_t clkidx, int dump, int verbose, int quiet, int replay)
</span> {
int err, ret = 0, vnq = verbose && !quiet;
const char *name = clock_names[clkidx];
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -825,6 +891,7 @@ report_clock(clock_idx_t clkidx, int dump, int verbose, int quiet)
</span>
if (vnq) printf(" Checking %s", name);
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* In replay mode, assume that current resolutions are acceptable */
</span> if ((err = getres(clkidx, &clock_res[clkidx]))) {
if (!vnq) {
printf("*** Error getting resolution of clock %s (%d): %s\n",
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -840,7 +907,8 @@ report_clock(clock_idx_t clkidx, int dump, int verbose, int quiet)
</span> }
if (vnq) printf(" (resolution = %d ns)\n", (int) clock_res[clkidx]);
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if ((err = check_clock(clkidx, &stats, &info))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((err = check_clock(clkidx, &stats, &info, quiet, replay))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (replay && info.retries < 0) return 0; /* Just skip nonex replay */
</span> report_clock_err(clkidx, &info, -1, verbose);
ret = 1;
}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -851,13 +919,13 @@ report_clock(clock_idx_t clkidx, int dump, int verbose, int quiet)
</span>
/* Report info about all clocks (singly) */
static int
<span style='display:block; white-space:pre;background:#ffe0e0;'>-report_all_clocks(int dump, int verbose, int quiet)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+report_all_clocks(int dump, int verbose, int quiet, int replay)
</span> {
int ret = 0;
clock_idx_t clkidx = 0;
while (clkidx < (clock_idx_t) clock_idx_max) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- ret |= report_clock(clkidx, dump, verbose, quiet);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret |= report_clock(clkidx, dump, verbose, quiet, replay);
</span> ++clkidx;
}
return ret;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1135,17 +1203,25 @@ get_dstats(clock_idx_t clkidx, dstats_t *dp)
</span> }
/* Get and check one clock and reference */
<span style='display:block; white-space:pre;background:#e0ffe0;'>+static int clock_replay_dual_ns(clock_idx_t clkidx, int quiet);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> static int
check_clock_sandwich(clock_idx_t clkidx,
<span style='display:block; white-space:pre;background:#ffe0e0;'>- errinfo_t *ei, errinfo_t *eir, dstats_t *dp)
</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;'>+ int quiet, int replay)
</span> {
int ret, tries = 0;
useconds_t sleepus = STD_SLEEP_US;
do {
ei->errnum = eir->errnum = errno = 0;
<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:#e0ffe0;'>+ if (!replay) {
</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;'>+ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ei->retries = -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if ((ret = clock_replay_dual_ns(clkidx, quiet))) return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> sleepus = MIN(sleepus * 2, MAX_SLEEP_US);
ret = check_samples(clock_idx_mach_absolute, refnsbuf, 0, eir);
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1155,7 +1231,7 @@ check_clock_sandwich(clock_idx_t clkidx,
</span> if (ret) { if (ret < 0) break; continue; }
ret = compare_clocks(clkidx, ei, eir, dp);
if (ret <= 0) break;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- } while (++tries < MAX_STEP_TRIES);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } while (!replay && ++tries < MAX_STEP_TRIES);
</span>
ei->retries = eir->retries = tries;
return ret;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1192,7 +1268,7 @@ clock_dump_dual_ns(clock_idx_t clkidx, errinfo_t *ei, errinfo_t *eir,
</span>
meanofs = (sns_time_t) (ei->first + ei->last - eir->first - eir->last) / 2;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- if (!(fp = open_log(clkidx, "-vs-mach", quiet))) return;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!(fp = open_log(clkidx, "-vs-mach", quiet, 0))) return;
</span> if (verbose >= 2) {
fprintf(fp, "# Comparison of %d %s samples vs. mach (%s)\n",
NUM_DIFFS, clock_names[clkidx],
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1241,20 +1317,64 @@ clock_dump_dual_ns(clock_idx_t clkidx, errinfo_t *ei, errinfo_t *eir,
</span> mean = (cur + next) / 2; diff = (sns_time_t) tstcur - mean - meanofs;
tstmin = tstcur - (next + ei->difflim);
tstmax = tstcur - (cur - ei->difflim);
<span style='display:block; white-space:pre;background:#ffe0e0;'>- fprintf(fp, "%7d %19llu %5d %19llu %+5lld %+5lld %+5lld\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(fp, " %6d %19llu %5d %19llu %+5lld %+5lld %+5lld\n",
</span> idx, ULL cur, (int) (cur - last),
ULL tstcur, LL diff, LL tstmin - meanofs, LL tstmax - meanofs);
last = cur;
}
cur = refnsbuf[idx];
<span style='display:block; white-space:pre;background:#ffe0e0;'>- fprintf(fp, "%7d %19llu %5d\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fprintf(fp, " %6d %19llu %5d\n",
</span> idx, ULL cur, (int) (cur - last));
fclose(fp);
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Replay data from prior dump */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+clock_replay_dual_ns(clock_idx_t clkidx, int quiet)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int ret = 0, count, idx = -1, diff1, diff2, ofs1, ofs2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ char pfx, sep, eol, buf[256];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ns_time_t cur, tstcur, *nsbuf = nsbufp[clock_types[clkidx]];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ FILE *fp;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!(fp = open_log(clkidx, "-vs-mach", quiet, 1))) return -1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ do {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!fgets(buf, sizeof(buf), fp)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = !feof(fp);
</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;'>+ count = sscanf(buf, "%c%d %llu %d%c%llu %lld %lld %lld%c",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ &pfx, &idx, ULLP &cur, &diff1, &sep,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ULLP &tstcur, LLP &diff2, LLP &ofs1, LLP &ofs2, &eol);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (count < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = 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;'>+ if (pfx == '#') continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (pfx != ' '
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ || !((count == 10 && sep == ' ' && eol == '\n')
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ || (count == 5 && sep == '\n'))) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!quiet) fprintf(stderr, " Bad line at/after index %d\n", idx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = -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;'>+ if (idx < 0 || idx >= NUM_SAMPLES
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ || (idx >= NUM_DIFFS && sep == ' ')) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (!quiet) fprintf(stderr, " Skipping bad index %d\n", idx);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ continue;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (sep == ' ') nsbuf[idx] = tstcur;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ refnsbuf[idx] = cur;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } while (1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ fclose(fp);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /* Report info about one clock comparison */
static int
<span style='display:block; white-space:pre;background:#ffe0e0;'>-report_clock_compare(clock_idx_t clkidx, int dump, int verbose, int quiet)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+report_clock_compare(clock_idx_t clkidx,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int dump, int verbose, int quiet, int replay)
</span> {
int ret = 0, vnq = verbose && !quiet;
const char *name = clock_names[clkidx];
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1263,7 +1383,8 @@ 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, &dstats)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (check_clock_sandwich(clkidx, &info, &refinfo, &dstats, quiet, replay)) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (replay && info.retries < 0) return 0; /* Just skip nonex replay */
</span> if (refinfo.errnum) {
report_clock_err(clock_idx_mach_absolute, &refinfo, 0, verbose);
}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1285,14 +1406,14 @@ report_clock_compare(clock_idx_t clkidx, int dump, int verbose, int quiet)
</span>
/* Report info about all clock comparisons */
static int
<span style='display:block; white-space:pre;background:#ffe0e0;'>-report_all_clock_compares(int dump, int verbose, int quiet)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+report_all_clock_compares(int dump, int verbose, int quiet, int replay)
</span> {
int ret = 0;
clock_idx_t clkidx = 0;
while (clkidx < (clock_idx_t) clock_idx_max) {
/* As sanity check, don't exclude self-compare */
<span style='display:block; white-space:pre;background:#ffe0e0;'>- ret |= report_clock_compare(clkidx, dump, verbose, quiet);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret |= report_clock_compare(clkidx, dump, verbose, quiet, replay);
</span> ++clkidx;
}
return ret;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1784,7 +1905,7 @@ int
</span> main(int argc, char *argv[])
{
int argn = 1;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- int continuous = 0, dump = 0, quiet = 0, verbose = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int continuous = 0, dump = 0, quiet = 0, replay = 0, verbose = 0;
</span> int err = 0, tterr, ttries;
const char *cp;
char chr;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1797,6 +1918,7 @@ main(int argc, char *argv[])
</span> case 'C': ++continuous; break;
case 'd': ++dump; break;
case 'q': ++quiet; break;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ case 'R': ++replay; break;
</span> case 'v': ++verbose; break;
}
}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1809,8 +1931,8 @@ main(int argc, char *argv[])
</span> err |= check_invalid();
while (!err) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- err |= report_all_clocks(dump, verbose, quiet);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>- err |= report_all_clock_compares(dump, verbose, quiet);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ err |= report_all_clocks(dump, verbose, quiet, replay);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ err |= report_all_clock_compares(dump, verbose, quiet, replay);
</span> err |= check_mach_scaling(verbose && !quiet);
/*
</pre><pre style='margin:0'>
</pre>