From: Jeremy Sinclair <4016293+snickler@users.noreply.github.com> Date: Wed, 14 Oct 2020 21:22:37 +0000 (-0400) Subject: Implemented clock_gettime_nsec_np in libraries for Apple Silicon support (#43343) X-Git-Tag: submit/tizen/20210909.063632~5075 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d67cc2cceb4dc8ecd15f5b6663d93f79de3954fd;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Implemented clock_gettime_nsec_np in libraries for Apple Silicon support (#43343) * Replaced mach_absolute_time instances with clock_gettime_nsec_np * Removed GetTimestampResolution method and replaced with 10^9 --- diff --git a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetTimestamp.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetTimestamp.cs index cd18a3a..a374e48 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetTimestamp.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetTimestamp.cs @@ -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(); diff --git a/src/libraries/Native/Unix/Common/pal_config.h.in b/src/libraries/Native/Unix/Common/pal_config.h.in index d889d10..856bd63 100644 --- a/src/libraries/Native/Unix/Common/pal_config.h.in +++ b/src/libraries/Native/Unix/Common/pal_config.h.in @@ -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 diff --git a/src/libraries/Native/Unix/System.Native/pal_time.c b/src/libraries/Native/Unix/System.Native/pal_time.c index decfbad..56e2313 100644 --- a/src/libraries/Native/Unix/System.Native/pal_time.c +++ b/src/libraries/Native/Unix/System.Native/pal_time.c @@ -12,8 +12,8 @@ #include #include #include -#if HAVE_MACH_ABSOLUTE_TIME -#include +#if HAVE_CLOCK_GETTIME_NSEC_NP +#include #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; diff --git a/src/libraries/Native/Unix/System.Native/pal_time.h b/src/libraries/Native/Unix/System.Native/pal_time.h index 44030df..12fe500 100644 --- a/src/libraries/Native/Unix/System.Native/pal_time.h +++ b/src/libraries/Native/Unix/System.Native/pal_time.h @@ -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); diff --git a/src/libraries/Native/Unix/configure.cmake b/src/libraries/Native/Unix/configure.cmake index 57e356f..6cb5616 100644 --- a/src/libraries/Native/Unix/configure.cmake +++ b/src/libraries/Native/Unix/configure.cmake @@ -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 diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.Unix.cs index 193886e..4879231 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.Unix.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.Unix.cs @@ -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()