Merge pull request #320 from apple/jblache/clock_monotonic

Base approximate time on a monotonic clock, like absolute time
diff --git a/configure.ac b/configure.ac
index fad99ec..4d7437d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -399,7 +399,7 @@
 #
 # Find functions and declarations we care about.
 #
-AC_CHECK_DECLS([CLOCK_UPTIME, CLOCK_MONOTONIC, CLOCK_REALTIME, CLOCK_UPTIME_FAST], [], [],
+AC_CHECK_DECLS([CLOCK_UPTIME, CLOCK_MONOTONIC, CLOCK_REALTIME, CLOCK_UPTIME_FAST, CLOCK_MONOTONIC_COARSE], [], [],
   [[#include <time.h>]])
 AC_CHECK_DECLS([NOTE_NONE, NOTE_REAP, NOTE_REVOKE, NOTE_SIGNAL, NOTE_LOWAT], [], [],
   [[#include <sys/event.h>]])
diff --git a/src/shims/time.h b/src/shims/time.h
index 0b8e926..6cc5a16 100644
--- a/src/shims/time.h
+++ b/src/shims/time.h
@@ -121,6 +121,19 @@
 #endif
 }
 
+/* On the use of clock sources in the CLOCK_MONOTONIC family
+ *
+ * The code below requires monotonic clock sources that only tick
+ * while the machine is running.
+ *
+ * Per POSIX, the CLOCK_MONOTONIC family is supposed to tick during
+ * machine sleep; this is not the case on Linux, and that behavior
+ * became part of the Linux ABI.
+ *
+ * Using the CLOCK_MONOTONIC family on POSIX-compliant platforms
+ * will lead to bugs, hence its use is restricted to Linux.
+ */
+
 static inline uint64_t
 _dispatch_absolute_time(void)
 {
@@ -130,7 +143,7 @@
 	struct timespec ts;
 	dispatch_assume_zero(clock_gettime(CLOCK_UPTIME, &ts));
 	return _dispatch_timespec_to_nano(ts);
-#elif HAVE_DECL_CLOCK_MONOTONIC
+#elif HAVE_DECL_CLOCK_MONOTONIC && defined(__linux__)
 	struct timespec ts;
 	dispatch_assume_zero(clock_gettime(CLOCK_MONOTONIC, &ts));
 	return _dispatch_timespec_to_nano(ts);
@@ -152,9 +165,9 @@
 	struct timespec ts;
 	dispatch_assume_zero(clock_gettime(CLOCK_UPTIME_FAST, &ts));
 	return _dispatch_timespec_to_nano(ts);
-#elif defined(__linux__)
+#elif HAVE_DECL_CLOCK_MONOTONIC_COARSE && defined(__linux__)
 	struct timespec ts;
-	dispatch_assume_zero(clock_gettime(CLOCK_REALTIME_COARSE, &ts));
+	dispatch_assume_zero(clock_gettime(CLOCK_MONOTONIC_COARSE, &ts));
 	return _dispatch_timespec_to_nano(ts);
 #else
 	return _dispatch_absolute_time();