Implemented clock_gettime_nsec_np in libraries for Apple Silicon support (#43343)
authorJeremy Sinclair <4016293+snickler@users.noreply.github.com>
Wed, 14 Oct 2020 21:22:37 +0000 (17:22 -0400)
committerGitHub <noreply@github.com>
Wed, 14 Oct 2020 21:22:37 +0000 (14:22 -0700)
* Replaced mach_absolute_time instances with clock_gettime_nsec_np

* Removed GetTimestampResolution method and replaced with 10^9

src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetTimestamp.cs
src/libraries/Native/Unix/Common/pal_config.h.in
src/libraries/Native/Unix/System.Native/pal_time.c
src/libraries/Native/Unix/System.Native/pal_time.h
src/libraries/Native/Unix/configure.cmake
src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.Unix.cs

index cd18a3a..a374e48 100644 (file)
@@ -7,9 +7,6 @@ internal static partial class Interop
 {
     internal static partial class Sys
     {
-        [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetTimestampResolution", ExactSpelling = true)]
-        internal static extern ulong GetTimestampResolution();
-
         [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetTimestamp", ExactSpelling = true)]
         [SuppressGCTransition]
         internal static extern ulong GetTimestamp();
index d889d10..856bd63 100644 (file)
@@ -85,7 +85,7 @@
 #cmakedefine01 HAVE_INOTIFY
 #cmakedefine01 HAVE_CLOCK_MONOTONIC
 #cmakedefine01 HAVE_CLOCK_REALTIME
-#cmakedefine01 HAVE_MACH_ABSOLUTE_TIME
+#cmakedefine01 HAVE_CLOCK_GETTIME_NSEC_NP
 #cmakedefine01 HAVE_TCP_H_TCPSTATE_ENUM
 #cmakedefine01 HAVE_TCP_FSM_H
 #cmakedefine01 HAVE_GSSFW_HEADERS
index decfbad..56e2313 100644 (file)
@@ -12,8 +12,8 @@
 #include <fcntl.h>
 #include <sys/time.h>
 #include <sys/resource.h>
-#if HAVE_MACH_ABSOLUTE_TIME
-#include <mach/mach_time.h>
+#if HAVE_CLOCK_GETTIME_NSEC_NP
+#include <time.h>
 #endif
 
 enum
@@ -47,40 +47,10 @@ int32_t SystemNative_UTimensat(const char* path, TimeSpec* times)
     return result;
 }
 
-// Gets the number of "ticks per second" of the underlying monotonic timer.
-//
-// On most Unix platforms, the methods that query the resolution return a value
-// that is "nanoseconds per tick" in which case we need to scale before returning.
-uint64_t SystemNative_GetTimestampResolution()
-{
-#if HAVE_MACH_ABSOLUTE_TIME
-    mach_timebase_info_data_t mtid;
-
-    if (mach_timebase_info(&mtid) != KERN_SUCCESS)
-    {
-        return 0;
-    }
-
-    // (numer / denom) gives you the nanoseconds per tick, so the below code
-    // computes the number of ticks per second. We explicitly do the multiplication
-    // first in order to help minimize the error that is produced by integer division.
-
-    return (SecondsToNanoSeconds * (uint64_t)(mtid.denom)) / (uint64_t)(mtid.numer);
-#else
-    // clock_gettime() returns a result in terms of nanoseconds rather than a count. This
-    // means that we need to either always scale the result by the actual resolution (to
-    // get a count) or we need to say the resolution is in terms of nanoseconds. We prefer
-    // the latter since it allows the highest throughput and should minimize error propagated
-    // to the user.
-
-    return SecondsToNanoSeconds;
-#endif
-}
-
 uint64_t SystemNative_GetTimestamp()
 {
-#if HAVE_MACH_ABSOLUTE_TIME
-    return mach_absolute_time();
+#if HAVE_CLOCK_GETTIME_NSEC_NP
+    return clock_gettime_nsec_np(CLOCK_UPTIME_RAW);
 #else
     struct timespec ts;
 
@@ -113,10 +83,7 @@ int32_t SystemNative_GetCpuUtilization(ProcessCpuInformation* previousCpuInfo)
             ((uint64_t)(resUsage.ru_utime.tv_usec) * MicroSecondsToNanoSeconds);
     }
 
-    uint64_t resolution = SystemNative_GetTimestampResolution();
-    uint64_t timestamp = SystemNative_GetTimestamp();
-
-    uint64_t currentTime = (uint64_t)((double)timestamp * ((double)SecondsToNanoSeconds / (double)resolution));
+    uint64_t currentTime = SystemNative_GetTimestamp();
 
     uint64_t lastRecordedCurrentTime = previousCpuInfo->lastRecordedCurrentTime;
     uint64_t lastRecordedKernelTime = previousCpuInfo->lastRecordedKernelTime;
index 44030df..12fe500 100644 (file)
@@ -28,11 +28,6 @@ typedef struct ProcessCpuInformation
 PALEXPORT int32_t SystemNative_UTimensat(const char* path, TimeSpec* times);
 
 /**
- * Gets the resolution of the timestamp, in counts per second.
- */
-PALEXPORT uint64_t SystemNative_GetTimestampResolution(void);
-
-/**
  * Gets a high-resolution timestamp that can be used for time-interval measurements.
  */
 PALEXPORT uint64_t SystemNative_GetTimestamp(void);
index 57e356f..6cb5616 100644 (file)
@@ -563,9 +563,9 @@ else()
 endif()
 
 check_symbol_exists(
-    mach_absolute_time
-    mach/mach_time.h
-    HAVE_MACH_ABSOLUTE_TIME)
+    clock_gettime_nsec_np
+    time.h
+    HAVE_CLOCK_GETTIME_NSEC_NP)
 
 check_symbol_exists(
     futimes
index 193886e..4879231 100644 (file)
@@ -7,7 +7,8 @@ namespace System.Diagnostics
     {
         private static long QueryPerformanceFrequency()
         {
-            return (long)Interop.Sys.GetTimestampResolution();
+            const long SecondsToNanoSeconds = 1000000000;
+            return SecondsToNanoSeconds;
         }
 
         private static long QueryPerformanceCounter()