<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/3a684d38b6f71337ec811768d47414cce1b4e0ad">https://github.com/macports/macports-legacy-support/commit/3a684d38b6f71337ec811768d47414cce1b4e0ad</a></p>
<pre style="white-space: pre; background: #F8F8F8"><span style='display:block; white-space:pre;color:#808000;'>commit 3a684d38b6f71337ec811768d47414cce1b4e0ad
</span>Author: Fred Wright <fw@fwright.net>
AuthorDate: Sat Feb 22 20:15:12 2025 -0800
<span style='display:block; white-space:pre;color:#404040;'> libtest_settime: Add boottime and mach time reports.
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> This permits observing the behavior of those clocks in the presence of
</span><span style='display:block; white-space:pre;color:#404040;'> a step adjustment in the system 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;'> Reports values when requested. Demonstrates difference in boottime
</span><span style='display:block; white-space:pre;color:#404040;'> behavior between <10.12 and 10.12+.
</span>---
manual_tests/libtest_settime.c | 103 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 97 insertions(+), 6 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/manual_tests/libtest_settime.c b/manual_tests/libtest_settime.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 27728ed..5aba3fa 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/manual_tests/libtest_settime.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/manual_tests/libtest_settime.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -46,6 +46,10 @@
</span> #include <sys/time.h>
#include <sys/types.h>
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <mach/clock.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <mach/mach.h>
</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> #define SLEEP_MS 500
#define TIME_BUMP_MS 100
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -62,15 +66,21 @@ typedef long long nstime_t;
</span> typedef struct info_s {
nstime_t init_raw;
nstime_t init_mono;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ nstime_t init_boot;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ nstime_t init_mach;
</span> nstime_t init_real;
nstime_t first_set;
nstime_t first_real;
nstime_t middle_raw;
nstime_t middle_mono;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ nstime_t middle_boot;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ nstime_t middle_mach;
</span> nstime_t middle_real;
nstime_t second_set;
nstime_t second_real;
nstime_t final_mono;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ nstime_t final_boot;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ nstime_t final_mach;
</span> nstime_t final_raw;
} info_t;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -100,8 +110,45 @@ clock_setns(nstime_t nsec)
</span> return 0;
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#define BILLION64 1000000000ULL
</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;'>+get_boottime_ns(nstime_t *nsp)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int ret;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ struct timeval bt;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ size_t boottime_len = sizeof(bt);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int bt_mib[] = {CTL_KERN, KERN_BOOTTIME};
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ size_t bt_miblen = sizeof(bt_mib) / sizeof(bt_mib[0]);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = sysctl(bt_mib, bt_miblen, &bt, &boottime_len, NULL, 0);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ *nsp = bt.tv_sec * BILLION64 + bt.tv_usec * 1000;
</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><span style='display:block; white-space:pre;background:#e0ffe0;'>+static clock_serv_t mclock = 0;
</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;'>+init_mach_clock(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ mach_port_t mach_host;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ mach_host = mach_host_self();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ host_get_clock_service(mach_host, SYSTEM_CLOCK, &mclock);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ mach_port_deallocate(mach_task_self(), mach_host);
</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 nstime_t
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+get_mach_clock_ns(void)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ mach_timespec_t mts;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ clock_get_time(mclock, &mts);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return mts.tv_sec * BILLION64 + mts.tv_nsec;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> static int
<span style='display:block; white-space:pre;background:#ffe0e0;'>-do_test(info_t *tp)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+do_test(info_t *tp, int extra)
</span> {
int err, tverr;
nstime_t delta, scratch;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -110,6 +157,9 @@ do_test(info_t *tp)
</span> /* First warm up the clocks */
(void) clock_getns(CLOCK_MONOTONIC_RAW, &scratch);
(void) clock_getns(CLOCK_MONOTONIC, &scratch);
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ (void) get_boottime_ns(&scratch);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ init_mach_clock();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ (void) get_mach_clock_ns();
</span> (void) clock_getns(CLOCK_REALTIME, &scratch);
/* Get us a fresh quantum */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -118,9 +168,13 @@ do_test(info_t *tp)
</span> /* Save original gettimeofday() time */
tverr = gettimeofday(&orig_tv, NULL);
<span style='display:block; white-space:pre;background:#ffe0e0;'>- /* Get both real and raw times, plus monotonic */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Get both real and raw times, plus monotonic and extras */
</span> if (clock_getns(CLOCK_MONOTONIC_RAW, &tp->init_raw)) return errno;
if (clock_getns(CLOCK_MONOTONIC, &tp->init_mono)) return errno;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (extra) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (get_boottime_ns(&tp->init_boot)) return errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ tp->init_mach = get_mach_clock_ns();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> if (clock_getns(CLOCK_REALTIME, &tp->init_real)) return errno;
/* Adjust clock forward */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -134,6 +188,10 @@ do_test(info_t *tp)
</span> if ((err = clock_getns(CLOCK_REALTIME, &tp->first_real))) break;
if ((err = clock_getns(CLOCK_MONOTONIC_RAW, &tp->middle_raw))) break;
if ((err = clock_getns(CLOCK_MONOTONIC, &tp->middle_mono))) break;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (extra) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (get_boottime_ns(&tp->middle_boot)) return errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ tp->middle_mach = get_mach_clock_ns();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> if ((err = clock_getns(CLOCK_REALTIME, &tp->middle_real))) break;
/* Adjust clock backward, can't fix it if it doesn't work */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -152,6 +210,10 @@ do_test(info_t *tp)
</span> /* Otherwise, finish up with a couple more captures */
if (clock_getns(CLOCK_REALTIME, &tp->second_real)) return errno;
if (clock_getns(CLOCK_MONOTONIC, &tp->final_mono)) return errno;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (extra) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (get_boottime_ns(&tp->final_boot)) return errno;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ tp->final_mach = get_mach_clock_ns();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> if (clock_getns(CLOCK_MONOTONIC_RAW, &tp->final_raw)) return errno;
/* Just to be safe, restore the time via settimeofday() */
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -173,18 +235,30 @@ do_test(info_t *tp)
</span> (long long) ptr->name)
static void
<span style='display:block; white-space:pre;background:#ffe0e0;'>-print_times(info_t *tp) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+print_times(info_t *tp, int extra) {
</span> PRINT_TIME(tp, init_raw);
PRINT_TIME(tp, init_mono);
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (extra) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ PRINT_TIME(tp, init_boot);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ PRINT_TIME(tp, init_mach);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> PRINT_TIME(tp, init_real);
PRINT_TIME(tp, first_set);
PRINT_TIME(tp, first_real);
PRINT_TIME(tp, middle_raw);
PRINT_TIME(tp, middle_mono);
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (extra) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ PRINT_TIME(tp, middle_boot);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ PRINT_TIME(tp, middle_mach);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> PRINT_TIME(tp, middle_real);
PRINT_TIME(tp, second_set);
PRINT_TIME(tp, second_real);
PRINT_TIME(tp, final_mono);
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (extra) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ PRINT_TIME(tp, final_boot);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ PRINT_TIME(tp, final_mach);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> PRINT_TIME(tp, final_raw);
}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -233,6 +307,7 @@ main(int argc, char *argv[])
</span> info_t info = {0};
if (argc > 1 && !strcmp(argv[1], "-v")) verbose = 1;
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (argc > 1 && !strcmp(argv[1], "-vv")) verbose = 2;
</span>
if (verbose) printf("%s starting.\n", basename(argv[0]));
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -271,7 +346,7 @@ main(int argc, char *argv[])
</span> }
/* Do the test */
<span style='display:block; white-space:pre;background:#ffe0e0;'>- err = do_test(&info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ err = do_test(&info, verbose >=2);
</span>
/* Undo our hogging */
unhog_cpus(threads, ncpus);
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -283,7 +358,7 @@ main(int argc, char *argv[])
</span> if (err) {
printf("Error encountered: %s\n", strerror(err));
printf("Dumping partial results:\n");
<span style='display:block; white-space:pre;background:#ffe0e0;'>- print_times(&info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ print_times(&info, verbose >= 2);
</span> return 1;
}
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -319,6 +394,22 @@ main(int argc, char *argv[])
</span> err = 1;
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ /* Also check mach monotonicity */
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (verbose >= 2) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (info.middle_mach < info.init_mach) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ printf("Middle mach %lld < init mach %lld, diff = %lld\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ info.middle_mach, info.init_mach,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ info.middle_mach - info.init_mach);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ err = 1;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ if (info.final_mach < info.middle_mach) {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ printf("Final mach %lld < middle mach %lld, diff = %lld\n",
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ info.final_mach, info.middle_mach,
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ info.final_mach - info.middle_mach);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ err = 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;'>+
</span> /* Now see if clock setting had reasonable effect */
if (llabs(diff1) > dur1 + FUDGE_NS) {
printf("First set/read delta was %lld ns, bracketed by %lld ns\n",
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -332,7 +423,7 @@ main(int argc, char *argv[])
</span> }
if (verbose) {
<span style='display:block; white-space:pre;background:#ffe0e0;'>- print_times(&info);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ print_times(&info, verbose >= 2);
</span> printf("Total ns = %lld\n", info.final_raw - info.init_raw);
}
</pre><pre style='margin:0'>
</pre>