<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/c0908bef36416902093daca7b1b67dc28489f571">https://github.com/macports/macports-legacy-support/commit/c0908bef36416902093daca7b1b67dc28489f571</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit c0908bef36416902093daca7b1b67dc28489f571
</span>Author: Fred Wright <fw@fwright.net>
AuthorDate: Fri Apr 25 18:36:51 2025 -0700

<span style='display:block; white-space:pre;color:#404040;'>    test_clocks: Ignore errors caused by Rosetta 2 bug.
</span><span style='display:block; white-space:pre;color:#404040;'>    
</span><span style='display:block; white-space:pre;color:#404040;'>    See comment for details.
</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;'>    Now passes on all platforms, including Rosetta 2.
</span>---
 test/test_clocks.c | 100 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 86 insertions(+), 14 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 b7a31c4..998076b 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;'>@@ -1388,6 +1388,64 @@ check_mach_scaling(int verbose)
</span>  * two nanosecond versions, and checks the triplet for consistency.
  */
 
<span style='display:block; white-space:pre;background:#e0ffe0;'>+/*
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Rosetta 2 bug
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * There is a bug in all current versions of Rosetta 2 that badly screws up
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * thread times.  Rosetta 2 pretends to have a 1GHz mach clock, to be more
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * like real x86 systems, and appropriately compensates for this in most
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * clock computations.  But the thread CPU-time calculation fails to do this,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * resulting in values that are off by a factor of the true mach-time ratio.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * E.g., on the M1 (mach ratio 125/3), the thread time is underreported by a
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * factor of ~41.7.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Note that this is not a legacy-support bug, since it only applies to OS
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * versions that don't use the legacy-support implementations of the clock
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * functions.  Nevertheless, the test is expected to pass on all OS versions,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * so we need to disable the failures in this case.  In the interests of full
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * disclosure, we don't disable the error messages; we only disable the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * failures.
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Although it might be possible to compensate for the error, this would be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * an unnecessary complication for a test primarily intended to test the
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * legacy-support code, not work around Apple's bugs.  It also might be
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * nontrivial to obtain the true mach-time scale factor when running under
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ * Rosetta 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;'>+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 110000 \
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    && defined(__x86_64__)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <sys/sysctl.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* sysctl to check whether we're running in Rosetta 2 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define SYSCTL_TRANSLATED "sysctl.proc_translated"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Test whether running under Rosetta */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* 0 no, 1 yes */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+check_rosetta(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int translated;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  size_t translated_sz = sizeof(translated);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  if (sysctlbyname(SYSCTL_TRANSLATED, &translated, &translated_sz,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+                   NULL, 0) < 0) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    /* If sysctl failed, must be really native. */
</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;'>+  return translated ? 1 : 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;'>+#else /* Not OS 11.x+ x86_64 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static int check_rosetta(void) { return 0;}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif /* Not OS 11.x+ x86_64 */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+/* Now back to our regularly scheduled clock tests */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> typedef void * (pthread_fn_t)(void *);
 
 /* Struct for both nsec and timespec captures */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1600,7 +1658,7 @@ thread_sleep(void *arg)
</span> static int
 check_thread_times(int verbose, int quiet)
 {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-  int ret = 0, wret = 0, eret = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int ret = 0, rret = 0, wret = 0, eret = 0;
</span>   ns_time_t start, end, wall, difflo, diffhi;
   dptime_t spin1 = {.func = thread_spin, .name = "spin1"};
   dptime_t spin2 = {.func = thread_spin, .name = "spin2"};
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1610,6 +1668,8 @@ check_thread_times(int verbose, int quiet)
</span>   const int numthreads = sizeof(threads) / sizeof(threads[0]);
   dptime_t *failed;
   double proclo, prochi, threadlo = 0.0, threadhi = 0.0;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+  int rosetta = check_rosetta();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+  int rquiet = rosetta && quiet;
</span> 
   if (verbose && !quiet) printf("  Checking thread times.\n");
 
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1664,37 +1724,45 @@ check_thread_times(int verbose, int quiet)
</span>     diffhi = spin1.end.after - spin1.start.before;
     threadlo += difflo / 1E6; threadhi += diffhi / 1E6;
     if (diffhi > wall) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-      printf("    *** Spin1 CPU %llu/%llu exceeds wall time %llu\n",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             ULL difflo, ULL diffhi, ULL wall);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-      ret = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (!rquiet) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        printf("    *** Spin1 CPU %llu/%llu exceeds wall time %llu\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+               ULL difflo, ULL diffhi, ULL wall);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (rosetta) rret = 1; else ret = 1;
</span>     }
   
     difflo = spin2.end.before - spin2.start.after;
     diffhi = spin2.end.after - spin2.start.before;
     threadlo += difflo / 1E6; threadhi += diffhi / 1E6;
     if (diffhi > wall) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-      printf("    *** Spin2 CPU %llu/%llu exceeds wall time %llu\n",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             ULL difflo, ULL diffhi, ULL wall);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-      ret = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (!rquiet) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        printf("    *** Spin2 CPU %llu/%llu exceeds wall time %llu\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+               ULL difflo, ULL diffhi, ULL wall);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (rosetta) rret = 1; else ret = 1;
</span>     }
   
     difflo = sleeper.end.before - sleeper.start.after;
     diffhi = sleeper.end.after - sleeper.start.before;
     threadlo += difflo / 1E6; threadhi += diffhi / 1E6;
     if (diffhi > THREAD_SLEEP_MAX_CPU * 1000) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-      printf("    *** Sleeper CPU %llu/%llu exceeds limit %llu\n",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             ULL difflo, ULL diffhi, ULL THREAD_SLEEP_MAX_CPU * 1000);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-      ret = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (!rquiet) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        printf("    *** Sleeper CPU %llu/%llu exceeds limit %llu\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+               ULL difflo, ULL diffhi, ULL THREAD_SLEEP_MAX_CPU * 1000);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (rosetta) rret = 1; else ret = 1;
</span>     }
 
     proclo = (top.end.before - top.start.after) / 1E6;
     prochi = (top.end.after - top.start.before) / 1E6;
     if (fabs(threadlo / prochi - 1.0) > TIME_SUM_TOLERANCE
         || fabs(threadhi / proclo - 1.0) > TIME_SUM_TOLERANCE) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>-      printf("    *** Total thread time %.6f/%.6f ms"
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             " mismatches process time %.6f/%.6f ms\n",
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-             threadlo, threadhi, proclo, prochi);
</span><span style='display:block; white-space:pre;background:#ffe0e0;'>-      ret = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (!rquiet) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+        printf("    *** Total thread time %.6f/%.6f ms"
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+               " mismatches process time %.6f/%.6f ms\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+               threadlo, threadhi, proclo, prochi);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      if (rosetta) rret = 1; else ret = 1;
</span>     }
 
     if (verbose && !quiet) {
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1702,6 +1770,10 @@ check_thread_times(int verbose, int quiet)
</span>              (threadlo / prochi - 1.0) * 100.0,
              (threadhi / proclo - 1.0) * 100.0);
     }
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    if (rret && !ret && !quiet) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+      printf("      Ignoring errors caused by Rosetta 2 bug\n");
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+    }
</span>   }
 
   return ret;
</pre><pre style='margin:0'>

</pre>