<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/3aa2dcdb035156271b48bd9f40a869527e692155">https://github.com/macports/macports-legacy-support/commit/3aa2dcdb035156271b48bd9f40a869527e692155</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 3aa2dcdb035156271b48bd9f40a869527e692155
</span>Author: Fred Wright <fw@fwright.net>
AuthorDate: Thu May 22 11:38:57 2025 -0700
<span style='display:block; white-space:pre;color:#404040;'> test_clocks: Add sleep time reporting.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> This measures "sleep time" as the difference between
</span><span style='display:block; white-space:pre;color:#404040;'> mach_continuous_time and mach_absolute_time, optionally reporting it,
</span><span style='display:block; white-space:pre;color:#404040;'> and checking for changes during the run.
</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;'> Gives plausible no-sleep results on all platforms. Sleeps aren't
</span><span style='display:block; white-space:pre;color:#404040;'> available in VMs, limiting the test cases for actual sleeps.
</span><span style='display:block; white-space:pre;color:#404040;'> Tested with sleeps on 10.4-10.5 ppc and 10.7-10.15 x86_64.
</span>---
test/test_clocks.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 84 insertions(+), 1 deletion(-)
<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 660ff9e..90a1683 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;'>@@ -72,6 +72,7 @@
</span> #define NUM_SAMPLES (NUM_DIFFS+1)
typedef uint64_t mach_time_t;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef int64_t smach_time_t;
</span> typedef struct timeval timeval_t;
typedef struct timespec timespec_t;
typedef uint64_t ns_time_t;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1951,6 +1952,70 @@ check_thread_times(int verbose, int quiet)
</span> return ret;
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Sleep offset (continuous - absolute time) functions */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+typedef struct sleepofs_s {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ smach_time_t ofs;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ smach_time_t toler;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+} sleepofs_t;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Obtain sleep offset */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+get_sleepofs(sleepofs_t *ofs)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int idx = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ mach_time_t std[4], *stp = &std[0];
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ mach_time_t cont[3], *ctp = &cont[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;'>+ * It's been empirically determined that a 4+3 sandwich is usually good
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * enough to get a "best" sandwich.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *stp++ = mach_absolute_time();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *ctp++ = mach_continuous_time();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *stp++ = mach_absolute_time();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *ctp++ = mach_continuous_time();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *stp++ = mach_absolute_time();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *ctp++ = mach_continuous_time();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *stp++ = mach_absolute_time();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Find tightest sandwich */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (std[idx+2] - std[idx+1] < std[idx+1] - std[idx]) ++idx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (std[idx+2] - std[idx+1] < std[idx+1] - std[idx]) ++idx;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ofs->ofs = cont[idx] - (std[idx+1] + std[idx]) / 2;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Round up and add one unit to tolerance */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ofs->toler = ((std[idx+1] - std[idx]) + 1 + 2) / 2;
</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;'>+/* Compare sleep offsets */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+compare_sleepofs(const sleepofs_t *ofs1, const sleepofs_t *ofs2)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Return 0 if ranges overlap */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (ofs1->ofs + ofs1->toler >= ofs2->ofs - ofs2->toler) return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (ofs2->ofs + ofs2->toler >= ofs1->ofs - ofs1->toler) return 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Else return comparison */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return ofs1->ofs < ofs2->ofs ? -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;'>+/* Report sleep offset */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+report_sleepofs(const char *text, const sleepofs_t *ofs)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ long double nanos = ofs->ofs * mach2nanos;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ double scaled;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ const char *units;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (nanos < 1E9) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ scaled = nanos / 1E6; units = "ms";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ scaled = nanos / 1E9; units = "sec";
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ printf("%s = %.6f %s +/- %.1f ns\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ text, scaled, units, (double) (ofs->toler * mach2nanos));
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> /* Main function */
int
main(int argc, char *argv[])
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1958,9 +2023,10 @@ main(int argc, char *argv[])
</span> int argn = 1;
int continuous = 0, dump = 0, keepgoing = 0;
int quiet = 0, replay = 0, verbose = 0;
<span style='display:block; white-space:pre;background:#ffe0e0;'>- int err = 0, tterr, ttries;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int err = 0, tterr, ttries, sleepchanged;
</span> const char *cp;
char chr;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ sleepofs_t lastsleep, cursleep;
</span>
strncpy(progname, basename(argv[0]), sizeof(progname));
while (argn < argc && argv[argn][0] == '-') {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1987,6 +2053,9 @@ main(int argc, char *argv[])
</span>
err |= check_invalid();
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ get_sleepofs(&lastsleep);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (verbose & !quiet) report_sleepofs(" Initial sleep offset", &lastsleep);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> while (!err || keepgoing) {
err |= report_all_clocks(dump, verbose, quiet, replay);
err |= report_all_clock_compares(dump, verbose, quiet, replay);
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -2005,6 +2074,20 @@ main(int argc, char *argv[])
</span> } while (tterr > 0 && --ttries);
err |= tterr;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ get_sleepofs(&cursleep);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ sleepchanged = compare_sleepofs(&cursleep, &lastsleep);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (sleepchanged) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (sleepchanged < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ printf(" *** Sleep offset went backwards\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ err = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ } else {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ printf(" *** Sleep offset changed\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ report_sleepofs(" Old sleep offset", &lastsleep);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ report_sleepofs(" New sleep offset", &cursleep);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ lastsleep = cursleep;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> if (!continuous || stopiter) break;
++iteration;
}
</pre><pre style='margin:0'>
</pre>