[master] e3363ac monotonic clock for macos

Nils Goroll nils.goroll at uplex.de
Tue Nov 8 20:22:04 CET 2016


commit e3363acc3a293904ad35f5110e0367380e93c27d
Author: Nils Goroll <nils.goroll at uplex.de>
Date:   Tue Nov 8 20:17:56 2016 +0100

    monotonic clock for macos
    
    The otherwise recommended clock_get_time(SYSTEM_TIME) is about 40x
    slower than mach_absolute_time() even after minimizing overhead by
    retrieving the port right only once per process - see
    https://github.com/nigoroll/varnish-cache/tree/macos_SYSTEM_CLOCK
    
    So we revert to mach_absolute_time() which needs some scaling but
    otherwise does the job. It is reported to halt on iOS devices when
    sleeping, but even if anyone came up with the idea to sell varnish
    over the app store, sleeping would probably need to be avoided in the
    first place and otherwise the right way would probably be to adjust
    the offset using pre/post sleep callbacks.
    
    As MacOS should have been the last platform using the real clock
    fallback for VTIM_mono, we now bail out at compile-time for any
    platform we have overlooked.

diff --git a/lib/libvarnish/vtim.c b/lib/libvarnish/vtim.c
index cd8c2ae..8b43f50 100644
--- a/lib/libvarnish/vtim.c
+++ b/lib/libvarnish/vtim.c
@@ -62,6 +62,9 @@
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
+#ifdef __MACH__
+#include <mach/mach_time.h>
+#endif
 
 #include "vas.h"
 #include "vtim.h"
@@ -87,6 +90,29 @@ static const int days_before_month[] = {
 	0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
 };
 
+#ifdef __MACH__
+// http://stackoverflow.com/a/21352348
+static uint64_t mt_base;
+static double   mt_scale;
+
+void
+mach_time_init(void)
+{
+	mach_timebase_info_data_t timebase;
+
+	mt_base = mach_absolute_time();
+
+	AZ(mach_timebase_info(&timebase));
+	mt_scale = (double)timebase.numer / (double)timebase.denom * 1e-9;
+}
+
+__attribute__((constructor)) void
+init(void)
+{
+	mach_time_init();
+}
+#endif
+
 /*
  * Note on Solaris: for some reason, clock_gettime(CLOCK_MONOTONIC, &ts) is not
  * implemented in assembly, but falls into a syscall, while gethrtime() doesn't,
@@ -103,11 +129,12 @@ VTIM_mono(void)
 
 	AZ(clock_gettime(CLOCK_MONOTONIC, &ts));
 	return (ts.tv_sec + 1e-9 * ts.tv_nsec);
-#else
-	struct timeval tv;
+#elif  defined(__MACH__)
+	uint64_t mt = mach_absolute_time() - mt_base;
 
-	AZ(gettimeofday(&tv, NULL));
-	return (tv.tv_sec + 1e-6 * tv.tv_usec);
+	return (mt * mt_scale);
+#else
+#error Varnish needs some monotonic time source
 #endif
 }
 



More information about the varnish-commit mailing list