[PATCH] D27429: [Chrono][Darwin] On Darwin use CLOCK_UPTIME_RAW instead of CLOCK_MONOTONIC

Bruno Cardoso Lopes via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 4 16:30:57 PST 2017


bruno updated this revision to Diff 83158.
bruno added a comment.

Thanks for the reviews. @howard.hinnant thanks for the great explanation & examples.

Attached a new version of the patch, addressing all suggestions. The logic became a bit simpler after Saleem's r290804, which already moved the CLOCK_MONOTONIC to be the last condition.

On top of that, I also conditionalized the presence of `clock_gettime`, which isn't available before 10.12 on macosx and specific versions on other apple platforms. Check that by looking at the deployment target.


https://reviews.llvm.org/D27429

Files:
  src/chrono.cpp


Index: src/chrono.cpp
===================================================================
--- src/chrono.cpp
+++ src/chrono.cpp
@@ -12,6 +12,28 @@
 #include "system_error"  // __throw_system_error
 #include <time.h>        // clock_gettime, CLOCK_MONOTONIC and CLOCK_REALTIME
 
+#if (__APPLE__)
+#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__)
+#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101200
+#define _LIBCXX_USE_CLOCK_GETTIME
+#endif
+#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__)
+#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 100000
+#define _LIBCXX_USE_CLOCK_GETTIME
+#endif
+#elif defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__)
+#if __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 100000
+#define _LIBCXX_USE_CLOCK_GETTIME
+#endif
+#elif defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__)
+#if __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 30000
+#define _LIBCXX_USE_CLOCK_GETTIME
+#endif
+#endif // __ENVIRONMENT_.*_VERSION_MIN_REQUIRED__
+#else
+#define _LIBCXX_USE_CLOCK_GETTIME
+#endif // __APPLE__
+
 #if defined(_LIBCPP_WIN32API)
 #define WIN32_LEAN_AND_MEAN
 #define VC_EXTRA_LEAN
@@ -70,16 +92,16 @@
                        static_cast<__int64>(ft.dwLowDateTime)};
   return time_point(duration_cast<duration>(d - nt_to_unix_epoch));
 #else
-#ifdef CLOCK_REALTIME
+#if defined(_LIBCXX_USE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
     struct timespec tp;
     if (0 != clock_gettime(CLOCK_REALTIME, &tp))
         __throw_system_error(errno, "clock_gettime(CLOCK_REALTIME) failed");
     return time_point(seconds(tp.tv_sec) + microseconds(tp.tv_nsec / 1000));
-#else  // !CLOCK_REALTIME
+#else
     timeval tv;
     gettimeofday(&tv, 0);
     return time_point(seconds(tv.tv_sec) + microseconds(tv.tv_usec));
-#endif  // CLOCK_REALTIME
+#endif // _LIBCXX_USE_CLOCK_GETTIME && CLOCK_REALTIME
 #endif
 }
 
@@ -106,6 +128,18 @@
 
 #if defined(__APPLE__)
 
+// Darwin libc versions >= 1133 provide ns precision via CLOCK_UPTIME_RAW
+#if defined(_LIBCXX_USE_CLOCK_GETTIME) && defined(CLOCK_UPTIME_RAW)
+steady_clock::time_point
+steady_clock::now() _NOEXCEPT
+{
+    struct timespec tp;
+    if (0 != clock_gettime(CLOCK_UPTIME_RAW, &tp))
+        __throw_system_error(errno, "clock_gettime(CLOCK_UPTIME_RAW) failed");
+    return time_point(seconds(tp.tv_sec) + nanoseconds(tp.tv_nsec));
+}
+
+#else
 //   mach_absolute_time() * MachInfo.numer / MachInfo.denom is the number of
 //   nanoseconds since the computer booted up.  MachInfo.numer and MachInfo.denom
 //   are run time constants supplied by the OS.  This clock has no relationship
@@ -157,6 +191,7 @@
     static FP fp = init_steady_clock();
     return time_point(duration(fp()));
 }
+#endif // defined(_LIBCXX_USE_CLOCK_GETTIME) && defined(CLOCK_UPTIME_RAW)
 
 #elif defined(_LIBCPP_WIN32API)
 
@@ -175,6 +210,13 @@
 
 #elif defined(CLOCK_MONOTONIC)
 
+// On Apple platforms only CLOCK_UPTIME_RAW or mach_absolute_time are able to
+// time functions in the nanosecond range. Thus, they are the only acceptable
+// implementations of steady_clock.
+#ifdef __APPLE__
+#error "Never use CLOCK_MONOTONIC for steady_clock::now on Apple platforms"
+#endif
+
 steady_clock::time_point
 steady_clock::now() _NOEXCEPT
 {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D27429.83158.patch
Type: text/x-patch
Size: 3244 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170105/a7086f84/attachment.bin>


More information about the cfe-commits mailing list