diff --git a/src/Common/src/Interop/Unix/System.Private.CoreLib.Native/Interop.HighPrecisionCounter.cs b/src/Common/src/Interop/Unix/System.Private.CoreLib.Native/Interop.HighPrecisionCounter.cs deleted file mode 100644 index 42e5db8a899..00000000000 --- a/src/Common/src/Interop/Unix/System.Private.CoreLib.Native/Interop.HighPrecisionCounter.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -internal static partial class Interop -{ - internal unsafe partial class Sys - { - [DllImport(Interop.Libraries.CoreLibNative, EntryPoint = "CoreLibNative_GetHighPrecisionCount")] - internal static extern ulong GetHighPrecisionCount(); - - [DllImport(Interop.Libraries.CoreLibNative, EntryPoint = "CoreLibNative_GetHighPrecisionCounterFrequency")] - internal static extern ulong GetHighPrecisionCounterFrequency(); - } -} diff --git a/src/Native/System.Private.CoreLib.Native/CMakeLists.txt b/src/Native/System.Private.CoreLib.Native/CMakeLists.txt index 8be3921b1b2..f1c27f447dc 100644 --- a/src/Native/System.Private.CoreLib.Native/CMakeLists.txt +++ b/src/Native/System.Private.CoreLib.Native/CMakeLists.txt @@ -1,7 +1,6 @@ project(System.Private.CoreLib.Native) set(NATIVE_SOURCES - pal_datetime.cpp pal_dynamicload.cpp pal_environment.cpp pal_errno.cpp diff --git a/src/Native/System.Private.CoreLib.Native/pal_datetime.cpp b/src/Native/System.Private.CoreLib.Native/pal_datetime.cpp deleted file mode 100644 index 19a97e5fdf0..00000000000 --- a/src/Native/System.Private.CoreLib.Native/pal_datetime.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#include -#include -#include - -static const int64_t SECS_TO_100NS = 10000000; /* 10^7 */ -static const int64_t MICROSECONDS_TO_100NS = 10; /* 1000 / 100 */ - -// -// CoreLibNative_GetSystemTimeAsTicks return the system time as ticks (100 nanoseconds) -// since 00:00 01 January 1970 UTC (Unix epoch) -// -extern "C" int64_t CoreLibNative_GetSystemTimeAsTicks() -{ - struct timeval time; - - if (gettimeofday(&time, NULL) != 0) - { - // in failure we return 00:00 01 January 1970 UTC (Unix epoch) - return 0; - } - - return ((int64_t) time.tv_sec) * SECS_TO_100NS + (time.tv_usec * MICROSECONDS_TO_100NS); -} diff --git a/src/Native/System.Private.CoreLib.Native/pal_time.cpp b/src/Native/System.Private.CoreLib.Native/pal_time.cpp index 136cb03bc82..1d7675373ad 100644 --- a/src/Native/System.Private.CoreLib.Native/pal_time.cpp +++ b/src/Native/System.Private.CoreLib.Native/pal_time.cpp @@ -35,66 +35,6 @@ mach_timebase_info_data_t *InitializeTimebaseInfo() } #endif -extern "C" uint64_t CoreLibNative_GetHighPrecisionCount() -{ - uint64_t counts = 0; - -#if HAVE_MACH_ABSOLUTE_TIME - { - counts = mach_absolute_time(); - } -#elif HAVE_CLOCK_MONOTONIC - { - clockid_t clockType = CLOCK_MONOTONIC; - struct timespec ts; - if (clock_gettime(clockType, &ts) != 0) - { - assert(false); - return counts; - } - counts = ts.tv_sec * NanosecondsPerSecond + ts.tv_nsec; - } -#else - { - struct timeval tv; - if (gettimeofday(&tv, nullptr) == -1) - { - assert(false); - return counts; - } - counts = tv.tv_sec * MicrosecondsPerSecond + tv.tv_usec; - } -#endif - return counts; -} - -#if HAVE_MACH_ABSOLUTE_TIME -static uint64_t s_highPrecisionCounterFrequency = 0; -#endif -extern "C" uint64_t CoreLibNative_GetHighPrecisionCounterFrequency() -{ -#if HAVE_MACH_ABSOLUTE_TIME - if (s_highPrecisionCounterFrequency != 0) - { - return s_highPrecisionCounterFrequency; - } - { - mach_timebase_info_data_t *machTimebaseInfo = GetMachTimebaseInfo(); - s_highPrecisionCounterFrequency = NanosecondsPerSecond * static_cast(machTimebaseInfo->denom) / machTimebaseInfo->numer; - } - return s_highPrecisionCounterFrequency; -#elif HAVE_CLOCK_MONOTONIC_COARSE || HAVE_CLOCK_MONOTONIC - { - return NanosecondsPerSecond; - } -#else - { - return MicrosecondsPerSecond; - } -#endif - return 0; -} - #define SECONDS_TO_MILLISECONDS 1000 #define MILLISECONDS_TO_MICROSECONDS 1000 #define MILLISECONDS_TO_NANOSECONDS 1000000 // 10^6 @@ -141,89 +81,3 @@ extern "C" uint64_t CoreLibNative_GetTickCount64() #endif return retval; } - - -struct ProcessCpuInformation -{ - uint64_t lastRecordedCurrentTime; - uint64_t lastRecordedKernelTime; - uint64_t lastRecordedUserTime; -}; - - -/* -Function: -CoreLibNative_GetCpuUtilization - -The main purpose of this function is to compute the overall CPU utilization -for the CLR thread pool to regulate the number of worker threads. -Since there is no consistent API on Unix to get the CPU utilization -from a user process, getrusage and gettimeofday are used to -compute the current process's CPU utilization instead. - -*/ - -static long numProcessors = 0; -extern "C" int32_t CoreLibNative_GetCpuUtilization(ProcessCpuInformation* previousCpuInfo) -{ - if (numProcessors <= 0) - { - numProcessors = sysconf(_SC_NPROCESSORS_CONF); - if (numProcessors <= 0) - { - return 0; - } - } - - uint64_t kernelTime = 0; - uint64_t userTime = 0; - - struct rusage resUsage; - if (getrusage(RUSAGE_SELF, &resUsage) == -1) - { - assert(false); - return 0; - } - else - { - kernelTime = TimeValToNanoseconds(resUsage.ru_stime); - userTime = TimeValToNanoseconds(resUsage.ru_utime); - } - - uint64_t currentTime = CoreLibNative_GetHighPrecisionCount() * NanosecondsPerSecond / CoreLibNative_GetHighPrecisionCounterFrequency(); - - uint64_t lastRecordedCurrentTime = previousCpuInfo->lastRecordedCurrentTime; - uint64_t lastRecordedKernelTime = previousCpuInfo->lastRecordedKernelTime; - uint64_t lastRecordedUserTime = previousCpuInfo->lastRecordedUserTime; - - uint64_t cpuTotalTime = 0; - if (currentTime > lastRecordedCurrentTime) - { - // cpuTotalTime is based on clock time. Since multiple threads can run in parallel, - // we need to scale cpuTotalTime cover the same amount of total CPU time. - // rusage time is already scaled across multiple processors. - cpuTotalTime = (currentTime - lastRecordedCurrentTime); - cpuTotalTime *= numProcessors; - } - - uint64_t cpuBusyTime = 0; - if (userTime >= lastRecordedUserTime && kernelTime >= lastRecordedKernelTime) - { - cpuBusyTime = (userTime - lastRecordedUserTime) + (kernelTime - lastRecordedKernelTime); - } - - int32_t cpuUtilization = 0; - if (cpuTotalTime > 0 && cpuBusyTime > 0) - { - cpuUtilization = static_cast(cpuBusyTime / cpuTotalTime); - } - - assert(cpuUtilization >= 0 && cpuUtilization <= 100); - - previousCpuInfo->lastRecordedCurrentTime = currentTime; - previousCpuInfo->lastRecordedUserTime = userTime; - previousCpuInfo->lastRecordedKernelTime = kernelTime; - - return cpuUtilization; -} - diff --git a/src/Common/src/Interop/Unix/System.Private.CoreLib.Native/Interop.GetCpuUtilization.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetCpuUtilization.cs similarity index 88% rename from src/Common/src/Interop/Unix/System.Private.CoreLib.Native/Interop.GetCpuUtilization.cs rename to src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetCpuUtilization.cs index 1f01d97a861..35e77c45419 100644 --- a/src/Common/src/Interop/Unix/System.Private.CoreLib.Native/Interop.GetCpuUtilization.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetCpuUtilization.cs @@ -18,7 +18,7 @@ internal struct ProcessCpuInformation ulong lastRecordedUserTime; } - [DllImport(Libraries.CoreLibNative, EntryPoint = "CoreLibNative_GetCpuUtilization")] + [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetCpuUtilization")] internal static extern unsafe int GetCpuUtilization(ref ProcessCpuInformation previousCpuInfo); } } diff --git a/src/Common/src/Interop/Unix/System.Native/Interop.GetSystemTimeAsTicks.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetSystemTimeAsTicks.cs similarity index 81% rename from src/Common/src/Interop/Unix/System.Native/Interop.GetSystemTimeAsTicks.cs rename to src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetSystemTimeAsTicks.cs index 795381fe138..d33b3f36853 100644 --- a/src/Common/src/Interop/Unix/System.Native/Interop.GetSystemTimeAsTicks.cs +++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetSystemTimeAsTicks.cs @@ -10,7 +10,7 @@ internal static partial class Interop { internal unsafe partial class Sys { - [DllImport(Interop.Libraries.CoreLibNative, EntryPoint = "CoreLibNative_GetSystemTimeAsTicks")] + [DllImport(Interop.Libraries.SystemNative, EntryPoint = "SystemNative_GetSystemTimeAsTicks")] internal static extern long GetSystemTimeAsTicks(); } } diff --git a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems index b113504b3d9..1fe9b28f690 100644 --- a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems +++ b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems @@ -1107,11 +1107,14 @@ + + + diff --git a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj index 5fb74f8e53e..5e59e4f9425 100644 --- a/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -413,7 +413,7 @@ Interop\Windows\mincore\Interop.DynamicLoad.cs - + @@ -461,7 +461,7 @@ - + @@ -477,24 +477,15 @@ Interop\Unix\Interop.Libraries.cs - - Interop\Unix\System.Private.CoreLib.Native\Interop.GetSystemTimeAsTicks.cs - Interop\Unix\System.Private.CoreLib.Native\Interop.Exit.cs - - Interop\Unix\System.Private.CoreLib.Native\Interop.GetCpuUtilization.cs - Interop\Unix\System.Private.CoreLib.Native\Interop.GetEnv.cs Interop\Unix\System.Private.CoreLib.Native\Interop.GetExecutableAbsolutePath.cs - - Interop\Unix\System.Private.CoreLib.Native\Interop.HighPrecisionCounter.cs - Interop\Unix\System.Private.CoreLib.Native\Interop.MemAllocFree.cs diff --git a/src/System.Private.CoreLib/src/System/HighPerformanceCounter.Unix.cs b/src/System.Private.CoreLib/src/System/HighPerformanceCounter.Unix.cs index 06298f0f804..b0e1256f214 100644 --- a/src/System.Private.CoreLib/src/System/HighPerformanceCounter.Unix.cs +++ b/src/System.Private.CoreLib/src/System/HighPerformanceCounter.Unix.cs @@ -2,13 +2,32 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Diagnostics; + namespace System { internal static class HighPerformanceCounter { - public static ulong TickCount => Interop.Sys.GetHighPrecisionCount(); + public static ulong TickCount + { + get + { + long tickCount; + bool success = Interop.Sys.GetTimestamp(out tickCount); + Debug.Assert(success); + return (ulong)tickCount; + } + } + + public static ulong Frequency { get; } = GetFrequency(); - // Cache the frequency on the managed side to avoid the cost of P/Invoke on every access to Frequency - public static ulong Frequency { get; } = Interop.Sys.GetHighPrecisionCounterFrequency(); + private static ulong GetFrequency() + { + // Cache the frequency on the managed side to avoid the cost of P/Invoke on every access to Frequency + long frequency; + bool success = Interop.Sys.GetTimestampResolution(out frequency); + Debug.Assert(success); + return (ulong)frequency; + } } }