diff --git a/src/coreclr/System.Private.CoreLib/src/System/Environment.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Environment.CoreCLR.cs index e0a24a42ef3223..8a10a83972b8ff 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Environment.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Environment.CoreCLR.cs @@ -108,21 +108,5 @@ private static unsafe string[] InitializeCommandLineArgs(char* exePath, int argc // Used by VM internal static string? GetResourceStringLocal(string key) => SR.GetResourceString(key); - - /// Gets the number of milliseconds elapsed since the system started. - /// A 32-bit signed integer containing the amount of time in milliseconds that has passed since the last time the computer was started. - public static extern int TickCount - { - [MethodImpl(MethodImplOptions.InternalCall)] - get; - } - - /// Gets the number of milliseconds elapsed since the system started. - /// A 64-bit signed integer containing the amount of time in milliseconds that has passed since the last time the computer was started. - public static extern long TickCount64 - { - [MethodImpl(MethodImplOptions.InternalCall)] - get; - } } } diff --git a/src/coreclr/classlibnative/bcltype/system.cpp b/src/coreclr/classlibnative/bcltype/system.cpp index 30845baa04b0b3..30b215f6c9d344 100644 --- a/src/coreclr/classlibnative/bcltype/system.cpp +++ b/src/coreclr/classlibnative/bcltype/system.cpp @@ -32,24 +32,6 @@ #include - -FCIMPL0(UINT32, SystemNative::GetTickCount) -{ - FCALL_CONTRACT; - - return ::GetTickCount(); -} -FCIMPLEND; - -FCIMPL0(UINT64, SystemNative::GetTickCount64) -{ - FCALL_CONTRACT; - - return ::GetTickCount64(); -} -FCIMPLEND; - - extern "C" VOID QCALLTYPE Environment_Exit(INT32 exitcode) { QCALL_CONTRACT; diff --git a/src/coreclr/classlibnative/bcltype/system.h b/src/coreclr/classlibnative/bcltype/system.h index 89d25005364d6f..11b4939cc715ea 100644 --- a/src/coreclr/classlibnative/bcltype/system.h +++ b/src/coreclr/classlibnative/bcltype/system.h @@ -37,9 +37,6 @@ class SystemNative public: // Functions on the System.Environment class - static FCDECL0(UINT32, GetTickCount); - static FCDECL0(UINT64, GetTickCount64); - static FCDECL1(VOID,SetExitCode,INT32 exitcode); static FCDECL0(INT32, GetExitCode); diff --git a/src/coreclr/debug/createdump/config.h.in b/src/coreclr/debug/createdump/config.h.in index 792d8a5988bef9..ee8701be0cf9c0 100644 --- a/src/coreclr/debug/createdump/config.h.in +++ b/src/coreclr/debug/createdump/config.h.in @@ -4,5 +4,3 @@ #pragma once #cmakedefine HAVE_PROCESS_VM_READV -#cmakedefine01 HAVE_CLOCK_GETTIME_NSEC_NP -#cmakedefine01 HAVE_CLOCK_MONOTONIC diff --git a/src/coreclr/debug/createdump/configure.cmake b/src/coreclr/debug/createdump/configure.cmake index 4ba6320f4c9309..9587b3f75f392a 100644 --- a/src/coreclr/debug/createdump/configure.cmake +++ b/src/coreclr/debug/createdump/configure.cmake @@ -1,22 +1,3 @@ check_function_exists(process_vm_readv HAVE_PROCESS_VM_READV) -check_symbol_exists( - clock_gettime_nsec_np - time.h - HAVE_CLOCK_GETTIME_NSEC_NP) - -check_cxx_source_runs(" -#include -#include -#include - -int main() -{ - int ret; - struct timespec ts; - ret = clock_gettime(CLOCK_MONOTONIC, &ts); - - exit(ret); -}" HAVE_CLOCK_MONOTONIC) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) diff --git a/src/coreclr/debug/createdump/createdumpmain.cpp b/src/coreclr/debug/createdump/createdumpmain.cpp index 5f54b07d03dfaf..b3426a31d2aa99 100644 --- a/src/coreclr/debug/createdump/createdumpmain.cpp +++ b/src/coreclr/debug/createdump/createdumpmain.cpp @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. #include "createdump.h" +#include "minipal/time.h" #ifdef HOST_WINDOWS #define DEFAULT_DUMP_PATH "%TEMP%\\" @@ -45,8 +46,6 @@ bool g_diagnostics = false; bool g_diagnosticsVerbose = false; uint64_t g_ticksPerMS = 0; uint64_t g_startTime = 0; -uint64_t GetTickFrequency(); -uint64_t GetTimeStamp(); // // Common entry point @@ -198,8 +197,8 @@ int createdump_main(const int argc, const char* argv[]) return -1; } - g_ticksPerMS = GetTickFrequency() / 1000UL; - g_startTime = GetTimeStamp(); + g_ticksPerMS = minipal_hires_tick_frequency() / 1000UL; + g_startTime = minipal_hires_ticks(); TRACE("TickFrequency: %d ticks per ms\n", g_ticksPerMS); ArrayHolder tmpPath = new char[MAX_LONGPATH]; @@ -221,11 +220,11 @@ int createdump_main(const int argc, const char* argv[]) if (CreateDump(options)) { - printf_status("Dump successfully written in %llums\n", GetTimeStamp() - g_startTime); + printf_status("Dump successfully written in %llums\n", (minipal_hires_ticks() - g_startTime) / g_ticksPerMS); } else { - printf_error("Failure took %llums\n", GetTimeStamp() - g_startTime); + printf_error("Failure took %llums\n", (minipal_hires_ticks() - g_startTime) / g_ticksPerMS); exitCode = -1; } @@ -332,24 +331,6 @@ printf_error(const char* format, ...) va_end(args); } -uint64_t -GetTickFrequency() -{ - LARGE_INTEGER ret; - ZeroMemory(&ret, sizeof(LARGE_INTEGER)); - QueryPerformanceFrequency(&ret); - return ret.QuadPart; -} - -uint64_t -GetTimeStamp() -{ - LARGE_INTEGER ret; - ZeroMemory(&ret, sizeof(LARGE_INTEGER)); - QueryPerformanceCounter(&ret); - return ret.QuadPart / g_ticksPerMS; -} - #ifdef HOST_UNIX static void @@ -360,7 +341,7 @@ trace_prefix(const char* format, va_list args) { fprintf(g_stdout, "[createdump] "); } - fprintf(g_stdout, "%08" PRIx64 " ", GetTimeStamp()); + fprintf(g_stdout, "%08" PRIx64 " ", minipal_hires_ticks() / g_ticksPerMS); vfprintf(g_stdout, format, args); fflush(g_stdout); } diff --git a/src/coreclr/debug/createdump/createdumppal.cpp b/src/coreclr/debug/createdump/createdumppal.cpp index 88e57ef7e8541c..fa6856ef2edf25 100644 --- a/src/coreclr/debug/createdump/createdumppal.cpp +++ b/src/coreclr/debug/createdump/createdumppal.cpp @@ -96,52 +96,6 @@ UninitializePAL( } } -#define tccSecondsToNanoSeconds 1000000000 // 10^9 - -BOOL -PALAPI -QueryPerformanceCounter( - OUT LARGE_INTEGER* lpPerformanceCount) -{ -#if HAVE_CLOCK_GETTIME_NSEC_NP - lpPerformanceCount->QuadPart = (LONGLONG)clock_gettime_nsec_np(CLOCK_UPTIME_RAW); -#elif HAVE_CLOCK_MONOTONIC - struct timespec ts; - int result = clock_gettime(CLOCK_MONOTONIC, &ts); - if (result != 0) - { - return TRUE; - } - else - { - lpPerformanceCount->QuadPart = ((LONGLONG)(ts.tv_sec) * (LONGLONG)(tccSecondsToNanoSeconds)) + (LONGLONG)(ts.tv_nsec); - } -#else - #error "The createdump requires either mach_absolute_time() or clock_gettime(CLOCK_MONOTONIC) to be supported." -#endif - return TRUE; -} - -BOOL -PALAPI -QueryPerformanceFrequency( - OUT LARGE_INTEGER* lpFrequency) -{ -#if HAVE_CLOCK_GETTIME_NSEC_NP - lpFrequency->QuadPart = (LONGLONG)(tccSecondsToNanoSeconds); -#elif HAVE_CLOCK_MONOTONIC - // 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. - lpFrequency->QuadPart = (LONGLONG)(tccSecondsToNanoSeconds); -#else - #error "The createdump requires either mach_absolute_time() or clock_gettime(CLOCK_MONOTONIC) to be supported." -#endif - return TRUE; -} - #define TEMP_DIRECTORY_PATH "/tmp/" DWORD diff --git a/src/coreclr/dlls/mscordac/mscordac_unixexports.src b/src/coreclr/dlls/mscordac/mscordac_unixexports.src index 206ae4091b7c82..a0d5128a5f48de 100644 --- a/src/coreclr/dlls/mscordac/mscordac_unixexports.src +++ b/src/coreclr/dlls/mscordac/mscordac_unixexports.src @@ -113,8 +113,6 @@ nativeStringResourceTable_mscorrc #OutputDebugStringW #OpenEventW #OutputDebugStringA -#QueryPerformanceCounter -#QueryPerformanceFrequency #RaiseException #RaiseFailFastException #ReadFile diff --git a/src/coreclr/gc/CMakeLists.txt b/src/coreclr/gc/CMakeLists.txt index 56956ed25f0496..a7bdcfc633368d 100644 --- a/src/coreclr/gc/CMakeLists.txt +++ b/src/coreclr/gc/CMakeLists.txt @@ -85,12 +85,14 @@ if(CLR_CMAKE_HOST_WIN32) advapi32.lib) endif(CLR_CMAKE_HOST_WIN32) -set (GC_LINK_LIBRARIES ${GC_LINK_LIBRARIES} gc_pal) +set (GC_LINK_LIBRARIES + ${GC_LINK_LIBRARIES} + gc_pal + minipal) if(CLR_CMAKE_TARGET_ARCH_AMD64) list(APPEND GC_LINK_LIBRARIES gc_vxsort - minipal ) endif(CLR_CMAKE_TARGET_ARCH_AMD64) diff --git a/src/coreclr/gc/unix/config.gc.h.in b/src/coreclr/gc/unix/config.gc.h.in index dfc38aea6b8470..cf6902460b9725 100644 --- a/src/coreclr/gc/unix/config.gc.h.in +++ b/src/coreclr/gc/unix/config.gc.h.in @@ -17,7 +17,6 @@ #cmakedefine01 HAVE_SYSCTLBYNAME #cmakedefine01 HAVE_PTHREAD_CONDATTR_SETCLOCK #cmakedefine01 HAVE_CLOCK_GETTIME_NSEC_NP -#cmakedefine01 HAVE_CLOCK_MONOTONIC #cmakedefine01 HAVE_SCHED_GETAFFINITY #cmakedefine01 HAVE_SCHED_SETAFFINITY #cmakedefine01 HAVE_PTHREAD_SETAFFINITY_NP diff --git a/src/coreclr/gc/unix/configure.cmake b/src/coreclr/gc/unix/configure.cmake index 8d33b81a32f727..0cc66c3e4aecea 100644 --- a/src/coreclr/gc/unix/configure.cmake +++ b/src/coreclr/gc/unix/configure.cmake @@ -89,20 +89,6 @@ check_symbol_exists( time.h HAVE_CLOCK_GETTIME_NSEC_NP) -check_cxx_source_runs(" -#include -#include -#include - -int main() -{ - int ret; - struct timespec ts; - ret = clock_gettime(CLOCK_MONOTONIC, &ts); - - exit(ret); -}" HAVE_CLOCK_MONOTONIC) - check_symbol_exists( posix_madvise sys/mman.h diff --git a/src/coreclr/gc/unix/gcenv.unix.cpp b/src/coreclr/gc/unix/gcenv.unix.cpp index 5a199f4b7db69e..2eb8e1acdba73d 100644 --- a/src/coreclr/gc/unix/gcenv.unix.cpp +++ b/src/coreclr/gc/unix/gcenv.unix.cpp @@ -24,6 +24,7 @@ #include "gcconfig.h" #include "numasupport.h" #include +#include #if HAVE_SWAPCTL #include @@ -1449,22 +1450,7 @@ void GCToOSInterface::GetMemoryStatus(uint64_t restricted_limit, uint32_t* memor // The counter value int64_t GCToOSInterface::QueryPerformanceCounter() { -#if HAVE_CLOCK_GETTIME_NSEC_NP - return (int64_t)clock_gettime_nsec_np(CLOCK_UPTIME_RAW); -#elif HAVE_CLOCK_MONOTONIC - struct timespec ts; - int result = clock_gettime(CLOCK_MONOTONIC, &ts); - - if (result != 0) - { - assert(!"clock_gettime(CLOCK_MONOTONIC) failed"); - __UNREACHABLE(); - } - - return ((int64_t)(ts.tv_sec) * (int64_t)(tccSecondsToNanoSeconds)) + (int64_t)(ts.tv_nsec); -#else -#error " clock_gettime(CLOCK_MONOTONIC) or clock_gettime_nsec_np() must be supported." -#endif + return minipal_hires_ticks(); } // Get a frequency of the high precision performance counter @@ -1473,7 +1459,7 @@ int64_t GCToOSInterface::QueryPerformanceCounter() int64_t GCToOSInterface::QueryPerformanceFrequency() { // The counter frequency of gettimeofday is in microseconds. - return tccSecondsToNanoSeconds; + return minipal_hires_tick_frequency(); } // Get a time stamp with a low precision @@ -1481,42 +1467,7 @@ int64_t GCToOSInterface::QueryPerformanceFrequency() // Time stamp in milliseconds uint64_t GCToOSInterface::GetLowPrecisionTimeStamp() { - uint64_t retval = 0; - -#if HAVE_CLOCK_GETTIME_NSEC_NP - retval = clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / tccMilliSecondsToNanoSeconds; -#elif HAVE_CLOCK_MONOTONIC - struct timespec ts; - -#if HAVE_CLOCK_MONOTONIC_COARSE - clockid_t clockType = CLOCK_MONOTONIC_COARSE; // good enough resolution, fastest speed -#else - clockid_t clockType = CLOCK_MONOTONIC; -#endif - - if (clock_gettime(clockType, &ts) != 0) - { -#if HAVE_CLOCK_MONOTONIC_COARSE - assert(!"clock_gettime(HAVE_CLOCK_MONOTONIC_COARSE) failed\n"); -#else - assert(!"clock_gettime(CLOCK_MONOTONIC) failed\n"); -#endif - } - - retval = (ts.tv_sec * tccSecondsToMilliSeconds) + (ts.tv_nsec / tccMilliSecondsToNanoSeconds); -#else - struct timeval tv; - if (gettimeofday(&tv, NULL) == 0) - { - retval = (tv.tv_sec * tccSecondsToMilliSeconds) + (tv.tv_usec / tccMilliSecondsToMicroSeconds); - } - else - { - assert(!"gettimeofday() failed\n"); - } -#endif - - return retval; + return (uint64_t)minipal_lowres_ticks(); } // Gets the total number of processors on the machine, not taking diff --git a/src/coreclr/ilasm/assembler.h b/src/coreclr/ilasm/assembler.h index b2b2d30a9c08dd..46a8119c073dd6 100644 --- a/src/coreclr/ilasm/assembler.h +++ b/src/coreclr/ilasm/assembler.h @@ -644,22 +644,22 @@ typedef FIFO MethodBodyList; struct Clockwork { - DWORD cBegin; - DWORD cEnd; - DWORD cParsBegin; - DWORD cParsEnd; - DWORD cMDInitBegin; - DWORD cMDInitEnd; - DWORD cMDEmitBegin; - DWORD cMDEmitEnd; - DWORD cMDEmit1; - DWORD cMDEmit2; - DWORD cMDEmit3; - DWORD cMDEmit4; - DWORD cRef2DefBegin; - DWORD cRef2DefEnd; - DWORD cFilegenBegin; - DWORD cFilegenEnd; + int64_t cBegin; + int64_t cEnd; + int64_t cParsBegin; + int64_t cParsEnd; + int64_t cMDInitBegin; + int64_t cMDInitEnd; + int64_t cMDEmitBegin; + int64_t cMDEmitEnd; + int64_t cMDEmit1; + int64_t cMDEmit2; + int64_t cMDEmit3; + int64_t cMDEmit4; + int64_t cRef2DefBegin; + int64_t cRef2DefEnd; + int64_t cFilegenBegin; + int64_t cFilegenEnd; }; struct TypeDefDescr diff --git a/src/coreclr/ilasm/ilasmpch.h b/src/coreclr/ilasm/ilasmpch.h index a6a62fe9ea814a..cbc5fd0b3d1d39 100644 --- a/src/coreclr/ilasm/ilasmpch.h +++ b/src/coreclr/ilasm/ilasmpch.h @@ -24,6 +24,7 @@ #include "mdfileformat.h" #include "stgpooli.h" +#include "minipal/time.h" #ifdef _EXPORT #undef _EXPORT diff --git a/src/coreclr/ilasm/main.cpp b/src/coreclr/ilasm/main.cpp index a7c824e4dfc397..da5fecb405b977 100644 --- a/src/coreclr/ilasm/main.cpp +++ b/src/coreclr/ilasm/main.cpp @@ -139,7 +139,7 @@ extern "C" int _cdecl wmain(int argc, _In_ WCHAR **argv) memset(pwzInputFiles,0,1024*sizeof(WCHAR*)); memset(pwzDeltaFiles,0,1024*sizeof(WCHAR*)); memset(&cw,0,sizeof(Clockwork)); - cw.cBegin = GetTickCount(); + cw.cBegin = minipal_lowres_ticks(); g_uConsoleCP = GetConsoleOutputCP(); memset(wzOutputFilename,0,sizeof(wzOutputFilename)); @@ -667,7 +667,7 @@ extern "C" int _cdecl wmain(int argc, _In_ WCHAR **argv) { int iFile; BOOL fAllFilesPresent = TRUE; - if(bClock) cw.cParsBegin = GetTickCount(); + if(bClock) cw.cParsBegin = minipal_lowres_ticks(); for(iFile = 0; iFile < NumFiles; iFile++) { uCodePage = CP_UTF8; @@ -723,7 +723,7 @@ extern "C" int _cdecl wmain(int argc, _In_ WCHAR **argv) delete pIn; } } // end for(iFile) - if(bClock) cw.cParsEnd = GetTickCount(); + if(bClock) cw.cParsEnd = minipal_lowres_ticks(); if ((pParser->Success() && fAllFilesPresent) || pAsm->OnErrGo) { HRESULT hr; @@ -746,7 +746,7 @@ extern "C" int _cdecl wmain(int argc, _In_ WCHAR **argv) } if(exitval == 0) // Write the output file { - if(bClock) cw.cFilegenEnd = GetTickCount(); + if(bClock) cw.cFilegenEnd = minipal_lowres_ticks(); if(pAsm->m_fReportProgress) pParser->msg("Writing PE file\n"); // Generate the file if (FAILED(hr = pAsm->m_pCeeFileGen->GenerateCeeFile(pAsm->m_pCeeFile))) @@ -764,7 +764,7 @@ extern "C" int _cdecl wmain(int argc, _In_ WCHAR **argv) pParser->msg("Failed to write PDB file, error code=0x%08X\n", hr); } } - if(bClock) cw.cEnd = GetTickCount(); + if(bClock) cw.cEnd = minipal_lowres_ticks(); if(exitval==0) { WCHAR wzNewOutputFilename[MAX_FILENAME_LENGTH+16]; @@ -854,21 +854,21 @@ extern "C" int _cdecl wmain(int argc, _In_ WCHAR **argv) if(bReportProgress) printf("Operation completed successfully\n"); if(bClock) { - printf("Timing (msec): Total run %d\n",(cw.cEnd-cw.cBegin)); - printf(" Startup %d\n",(cw.cParsBegin-cw.cBegin)); - printf(" - MD initialization %d\n",(cw.cMDInitEnd - cw.cMDInitBegin)); - printf(" Parsing %d\n",(cw.cParsEnd - cw.cParsBegin)); - printf(" Emitting MD %d\n",(cw.cMDEmitEnd - cw.cRef2DefEnd)+(cw.cRef2DefBegin - cw.cMDEmitBegin)); - //printf(" - global fixups %d\n",(cw.cMDEmit1 - cw.cMDEmitBegin)); - printf(" - SN sig alloc %d\n",(cw.cMDEmit2 - cw.cMDEmitBegin)); - printf(" - Classes,Methods,Fields %d\n",(cw.cRef2DefBegin - cw.cMDEmit2)); - printf(" - Events,Properties %d\n",(cw.cMDEmit3 - cw.cRef2DefEnd)); - printf(" - MethodImpls %d\n",(cw.cMDEmit4 - cw.cMDEmit3)); - printf(" - Manifest,CAs %d\n",(cw.cMDEmitEnd - cw.cMDEmit4)); - printf(" Ref to Def resolution %d\n",(cw.cRef2DefEnd - cw.cRef2DefBegin)); - printf(" Fixup and linking %d\n",(cw.cFilegenBegin - cw.cMDEmitEnd)); - printf(" CEE file generation %d\n",(cw.cFilegenEnd - cw.cFilegenBegin)); - printf(" PE file writing %d\n",(cw.cEnd - cw.cFilegenEnd)); + printf("Timing (msec): Total run %d\n",(int)(cw.cEnd-cw.cBegin)); + printf(" Startup %d\n",(int)(cw.cParsBegin-cw.cBegin)); + printf(" - MD initialization %d\n",(int)(cw.cMDInitEnd - cw.cMDInitBegin)); + printf(" Parsing %d\n",(int)(cw.cParsEnd - cw.cParsBegin)); + printf(" Emitting MD %d\n",(int)(cw.cMDEmitEnd - cw.cRef2DefEnd)+(int)(cw.cRef2DefBegin - cw.cMDEmitBegin)); + //printf(" - global fixups %d\n",(int)(cw.cMDEmit1 - cw.cMDEmitBegin)); + printf(" - SN sig alloc %d\n",(int)(cw.cMDEmit2 - cw.cMDEmitBegin)); + printf(" - Classes,Methods,Fields %d\n",(int)(cw.cRef2DefBegin - cw.cMDEmit2)); + printf(" - Events,Properties %d\n",(int)(cw.cMDEmit3 - cw.cRef2DefEnd)); + printf(" - MethodImpls %d\n",(int)(cw.cMDEmit4 - cw.cMDEmit3)); + printf(" - Manifest,CAs %d\n",(int)(cw.cMDEmitEnd - cw.cMDEmit4)); + printf(" Ref to Def resolution %d\n",(int)(cw.cRef2DefEnd - cw.cRef2DefBegin)); + printf(" Fixup and linking %d\n",(int)(cw.cFilegenBegin - cw.cMDEmitEnd)); + printf(" CEE file generation %d\n",(int)(cw.cFilegenEnd - cw.cFilegenBegin)); + printf(" PE file writing %d\n",(int)(cw.cEnd - cw.cFilegenEnd)); } } else diff --git a/src/coreclr/ilasm/writer.cpp b/src/coreclr/ilasm/writer.cpp index 1667f0fdea1abb..9b05cd6aa13692 100644 --- a/src/coreclr/ilasm/writer.cpp +++ b/src/coreclr/ilasm/writer.cpp @@ -28,7 +28,7 @@ HRESULT Assembler::InitMetaData() if(m_fInitialisedMetaData) return S_OK; - if(bClock) bClock->cMDInitBegin = GetTickCount(); + if(bClock) bClock->cMDInitBegin = minipal_lowres_ticks(); hr = MetaDataGetDispenser(CLSID_CorMetaDataDispenser, IID_IMetaDataDispenserEx2, (void **)&m_pDisp); @@ -93,7 +93,7 @@ HRESULT Assembler::InitMetaData() hr = S_OK; exit: - if(bClock) bClock->cMDInitEnd = GetTickCount(); + if(bClock) bClock->cMDInitEnd = minipal_lowres_ticks(); return hr; } /*********************************************************************************/ @@ -1172,7 +1172,7 @@ HRESULT Assembler::CreatePEFile(_In_ __nullterminated WCHAR *pwzOutputFilename) GUID deterministicGuid = GUID(); ULONG deterministicTimestamp = 0; - if(bClock) bClock->cMDEmitBegin = GetTickCount(); + if(bClock) bClock->cMDEmitBegin = minipal_lowres_ticks(); if(m_fReportProgress) printf("Creating PE file\n"); if (!m_pEmitter) { @@ -1185,7 +1185,7 @@ HRESULT Assembler::CreatePEFile(_In_ __nullterminated WCHAR *pwzOutputFilename) if(!OnErrGo) return E_FAIL; } - if(bClock) bClock->cMDEmit1 = GetTickCount(); + if(bClock) bClock->cMDEmit1 = minipal_lowres_ticks(); // Allocate space for a strong name signature if we're delay or full // signing the assembly. @@ -1200,7 +1200,7 @@ HRESULT Assembler::CreatePEFile(_In_ __nullterminated WCHAR *pwzOutputFilename) m_dwComImageFlags |= COMIMAGE_FLAGS_STRONGNAMESIGNED; } - if(bClock) bClock->cMDEmit2 = GetTickCount(); + if(bClock) bClock->cMDEmit2 = minipal_lowres_ticks(); if(m_VTFList.COUNT()==0) { @@ -1327,9 +1327,9 @@ HRESULT Assembler::CreatePEFile(_In_ __nullterminated WCHAR *pwzOutputFilename) } // All ref'ed items def'ed in this file are emitted, resolve member refs to member defs: - if(bClock) bClock->cRef2DefBegin = GetTickCount(); + if(bClock) bClock->cRef2DefBegin = minipal_lowres_ticks(); hr = ResolveLocalMemberRefs(); - if(bClock) bClock->cRef2DefEnd = GetTickCount(); + if(bClock) bClock->cRef2DefEnd = minipal_lowres_ticks(); if(FAILED(hr) &&(!OnErrGo)) goto exit; // Local member refs resolved, emit events, props and method impls @@ -1352,7 +1352,7 @@ HRESULT Assembler::CreatePEFile(_In_ __nullterminated WCHAR *pwzOutputFilename) pSearch->m_fNewMembers = FALSE; } } - if(bClock) bClock->cMDEmit3 = GetTickCount(); + if(bClock) bClock->cMDEmit3 = minipal_lowres_ticks(); if(m_MethodImplDList.COUNT()) { if(m_fReportProgress) report->msg("Method Implementations (total): %d\n",m_MethodImplDList.COUNT()); @@ -1362,7 +1362,7 @@ HRESULT Assembler::CreatePEFile(_In_ __nullterminated WCHAR *pwzOutputFilename) } } // Emit the rest of the metadata - if(bClock) bClock->cMDEmit4 = GetTickCount(); + if(bClock) bClock->cMDEmit4 = minipal_lowres_ticks(); hr = S_OK; if(m_pManifest) { @@ -1400,7 +1400,7 @@ HRESULT Assembler::CreatePEFile(_In_ __nullterminated WCHAR *pwzOutputFilename) delete pTDD; } } - if(bClock) bClock->cMDEmitEnd = GetTickCount(); + if(bClock) bClock->cMDEmitEnd = minipal_lowres_ticks(); hr = DoLocalMemberRefFixups(); if(FAILED(hr) &&(!OnErrGo)) goto exit; @@ -1709,7 +1709,7 @@ HRESULT Assembler::CreatePEFile(_In_ __nullterminated WCHAR *pwzOutputFilename) if (FAILED(hr)) goto exit; } - if(bClock) bClock->cFilegenBegin = GetTickCount(); + if(bClock) bClock->cFilegenBegin = minipal_lowres_ticks(); // actually output the meta-data if (FAILED(hr=m_pCeeFileGen->EmitMetaDataAt(m_pCeeFile, m_pEmitter, m_pILSection, metaDataOffset, metaData, metaDataSize))) goto exit; diff --git a/src/coreclr/inc/random.h b/src/coreclr/inc/random.h index 6a8d7001b20430..98d24d2f17834b 100644 --- a/src/coreclr/inc/random.h +++ b/src/coreclr/inc/random.h @@ -19,6 +19,7 @@ #define _CLRRANDOM_H_ #include +#include "minipal/time.h" // // Forbid the use of srand()/rand(), as these are globally shared facilities and our use of them would @@ -73,10 +74,7 @@ class CLRRandom void Init() { LIMITED_METHOD_CONTRACT; - LARGE_INTEGER time; - if (!QueryPerformanceCounter(&time)) - time.QuadPart = GetTickCount(); - Init((int)time.u.LowPart ^ GetCurrentThreadId() ^ GetCurrentProcessId()); + Init((int)minipal_hires_ticks() ^ GetCurrentThreadId() ^ GetCurrentProcessId()); } void Init(int Seed) diff --git a/src/coreclr/inc/utilcode.h b/src/coreclr/inc/utilcode.h index b94b6b45866a5c..d36b1627e611c9 100644 --- a/src/coreclr/inc/utilcode.h +++ b/src/coreclr/inc/utilcode.h @@ -729,8 +729,6 @@ void SplitPathInterior( #include "ostype.h" -#define CLRGetTickCount64() GetTickCount64() - // // Allocate free memory within the range [pMinAddr..pMaxAddr] using // ClrVirtualQuery to find free memory and ClrVirtualAlloc to allocate it. diff --git a/src/coreclr/jit/CMakeLists.txt b/src/coreclr/jit/CMakeLists.txt index f8167e8ae94241..1cfe40b6853a25 100644 --- a/src/coreclr/jit/CMakeLists.txt +++ b/src/coreclr/jit/CMakeLists.txt @@ -532,6 +532,7 @@ add_custom_target(jit_exports DEPENDS ${JIT_EXPORTS_FILE}) set(JIT_LINK_LIBRARIES utilcodestaticnohost + minipal ) set(JIT_ARCH_LINK_LIBRARIES diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index d085ef712a40fb..a4b3ae17b3d9f4 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -22,6 +22,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #include "stacklevelsetter.h" #include "patchpointinfo.h" #include "jitstd/algorithm.h" +#include "minipal/time.h" extern ICorJitHost* g_jitHost; @@ -9259,12 +9260,7 @@ void Compiler::PrintPerMethodLoopHoistStats() void Compiler::RecordStateAtEndOfInlining() { #if defined(DEBUG) - LARGE_INTEGER lpCycles; - BOOL result = QueryPerformanceCounter(&lpCycles); - if (result == TRUE) - { - m_compCyclesAtEndOfInlining = (int64_t)lpCycles.QuadPart; - } + m_compCyclesAtEndOfInlining = minipal_hires_ticks(); #endif // defined(DEBUG) } @@ -9277,21 +9273,13 @@ void Compiler::RecordStateAtEndOfCompilation() #if defined(DEBUG) m_compCycles = 0; - LARGE_INTEGER lpCycles; - BOOL result = QueryPerformanceCounter(&lpCycles); - if (result == TRUE) + int64_t lpCycles = minipal_hires_ticks(); + if (lpCycles > m_compCyclesAtEndOfInlining) { - if ((int64_t)lpCycles.QuadPart > m_compCyclesAtEndOfInlining) - { - LARGE_INTEGER lpFreq; - result = QueryPerformanceFrequency(&lpFreq); - if (result == TRUE) - { - m_compCycles = (int64_t)lpCycles.QuadPart - m_compCyclesAtEndOfInlining; - m_compCycles *= 1000000; - m_compCycles /= (int64_t)lpFreq.QuadPart; - } - } + int64_t lpFreq = minipal_hires_tick_frequency(); + m_compCycles = lpCycles - m_compCyclesAtEndOfInlining; + m_compCycles *= 1000000; + m_compCycles /= lpFreq; } #endif // defined(DEBUG) } diff --git a/src/coreclr/jit/utils.cpp b/src/coreclr/jit/utils.cpp index a9101620f3f2c8..44b7762d8407cd 100644 --- a/src/coreclr/jit/utils.cpp +++ b/src/coreclr/jit/utils.cpp @@ -23,6 +23,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #include "opcode.h" #include "jitstd/algorithm.h" +#include "minipal/time.h" /*****************************************************************************/ @@ -2196,22 +2197,15 @@ double CycleCount::ElapsedTime() bool PerfCounter::Start() { - bool result = QueryPerformanceFrequency(&beg) != 0; - if (!result) - { - return result; - } - freq = (double)beg.QuadPart / 1000.0; - (void)QueryPerformanceCounter(&beg); - return result; + freq = (double)minipal_hires_tick_frequency() / 1000.0; + beg = minipal_hires_ticks(); + return true; } // Return elapsed time from Start() in millis. double PerfCounter::ElapsedTime() { - LARGE_INTEGER li; - (void)QueryPerformanceCounter(&li); - return (double)(li.QuadPart - beg.QuadPart) / freq; + return (double)(minipal_hires_ticks() - beg) / freq; } #endif diff --git a/src/coreclr/jit/utils.h b/src/coreclr/jit/utils.h index 3d3ef423b44b9b..75edcb4d802848 100644 --- a/src/coreclr/jit/utils.h +++ b/src/coreclr/jit/utils.h @@ -785,11 +785,11 @@ class CycleCount bool GetCycles(uint64_t* time); }; -// Uses win API QueryPerformanceCounter/QueryPerformanceFrequency. +// Uses minipal/time.h class PerfCounter { - LARGE_INTEGER beg; - double freq; + int64_t beg; + double freq; public: // If the method returns false, any other query yield unpredictable results. diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs index 99964658199f0f..5909087c68708e 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs @@ -280,9 +280,6 @@ internal static extern unsafe IntPtr RhpCallPropagateExceptionCallback( [DllImport(Redhawk.BaseName)] internal static extern void RhpSignalFinalizationComplete(uint fCount, int observedFullGcCount); - [DllImport(Redhawk.BaseName)] - internal static extern ulong RhpGetTickCount64(); - // Enters a no GC region, possibly doing a blocking GC if there is not enough // memory available to satisfy the caller's request. [DllImport(Redhawk.BaseName)] diff --git a/src/coreclr/nativeaot/Runtime/CommonMacros.h b/src/coreclr/nativeaot/Runtime/CommonMacros.h index 426e0119209b9e..c174b06f17ccd4 100644 --- a/src/coreclr/nativeaot/Runtime/CommonMacros.h +++ b/src/coreclr/nativeaot/Runtime/CommonMacros.h @@ -6,6 +6,9 @@ #include "rhassert.h" #include +#ifdef PROFILE_STARTUP +#include +#endif #define EXTERN_C extern "C" @@ -323,7 +326,7 @@ enum STARTUP_TIMELINE_EVENT_ID #ifdef PROFILE_STARTUP extern uint64_t g_startupTimelineEvents[NUM_STARTUP_TIMELINE_EVENTS]; -#define STARTUP_TIMELINE_EVENT(eventid) g_startupTimelineEvents[eventid] = PalQueryPerformanceCounter(); +#define STARTUP_TIMELINE_EVENT(eventid) g_startupTimelineEvents[eventid] = (uint64_t)minipal_hires_ticks(); #else // PROFILE_STARTUP #define STARTUP_TIMELINE_EVENT(eventid) #endif // PROFILE_STARTUP diff --git a/src/coreclr/nativeaot/Runtime/GcStressControl.cpp b/src/coreclr/nativeaot/Runtime/GcStressControl.cpp index 3f9853a3ea3b1e..ad3d9dfdd9ae8d 100644 --- a/src/coreclr/nativeaot/Runtime/GcStressControl.cpp +++ b/src/coreclr/nativeaot/Runtime/GcStressControl.cpp @@ -25,6 +25,7 @@ #include "shash.h" #include "shash.inl" #include "GcStressControl.h" +#include "minipal/time.h" class GcStressControl @@ -70,7 +71,7 @@ class GcStressControl if (g_pRhConfig->GetGcStressSeed()) s_lGcStressRNGSeed = (uint32_t)g_pRhConfig->GetGcStressSeed(); else - s_lGcStressRNGSeed = (uint32_t)PalGetTickCount64(); + s_lGcStressRNGSeed = (uint32_t)minipal_lowres_ticks(); if (g_pRhConfig->GetGcStressFreqDenom()) s_lGcStressFreqDenom = (uint32_t)g_pRhConfig->GetGcStressFreqDenom(); diff --git a/src/coreclr/nativeaot/Runtime/MiscHelpers.cpp b/src/coreclr/nativeaot/Runtime/MiscHelpers.cpp index 530ec8403dde50..9fe749e23ed8c8 100644 --- a/src/coreclr/nativeaot/Runtime/MiscHelpers.cpp +++ b/src/coreclr/nativeaot/Runtime/MiscHelpers.cpp @@ -36,6 +36,7 @@ #include "RhConfig.h" #include #include +#include FCIMPL0(void, RhDebugBreak) { @@ -418,11 +419,6 @@ FCIMPL1(uint8_t *, RhGetCodeTarget, uint8_t * pCodeOrg) } FCIMPLEND -EXTERN_C uint64_t QCALLTYPE RhpGetTickCount64() -{ - return PalGetTickCount64(); -} - EXTERN_C int32_t QCALLTYPE RhpCalculateStackTraceWorker(void* pOutputBuffer, uint32_t outputBufferLength, void* pAddressInCurrentFrame); EXTERN_C int32_t QCALLTYPE RhpGetCurrentThreadStackTrace(void* pOutputBuffer, uint32_t outputBufferLength, void* pAddressInCurrentFrame) diff --git a/src/coreclr/nativeaot/Runtime/PalRedhawk.h b/src/coreclr/nativeaot/Runtime/PalRedhawk.h index adc2deaf208e5b..167570b165d199 100644 --- a/src/coreclr/nativeaot/Runtime/PalRedhawk.h +++ b/src/coreclr/nativeaot/Runtime/PalRedhawk.h @@ -283,7 +283,6 @@ REDHAWK_PALIMPORT void REDHAWK_PALAPI PalSleep(uint32_t milliseconds); REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalSwitchToThread(); REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalAreShadowStacksEnabled(); REDHAWK_PALIMPORT HANDLE REDHAWK_PALAPI PalCreateEventW(_In_opt_ LPSECURITY_ATTRIBUTES pEventAttributes, UInt32_BOOL manualReset, UInt32_BOOL initialState, _In_opt_z_ LPCWSTR pName); -REDHAWK_PALIMPORT uint64_t REDHAWK_PALAPI PalGetTickCount64(); REDHAWK_PALIMPORT HANDLE REDHAWK_PALAPI PalGetModuleHandleFromPointer(_In_ void* pointer); #ifdef TARGET_UNIX @@ -325,9 +324,6 @@ REDHAWK_PALIMPORT void REDHAWK_PALAPI PalAttachThread(void* thread); REDHAWK_PALIMPORT uint64_t PalGetCurrentOSThreadId(); -REDHAWK_PALIMPORT uint64_t PalQueryPerformanceCounter(); -REDHAWK_PALIMPORT uint64_t PalQueryPerformanceFrequency(); - REDHAWK_PALIMPORT void PalPrintFatalError(const char* message); REDHAWK_PALIMPORT char* PalCopyTCharAsChar(const TCHAR* toCopy); diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp index 9b2bb852239647..20d557ec6f8e81 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp +++ b/src/coreclr/nativeaot/Runtime/eventpipe/ep-rt-aot.cpp @@ -18,6 +18,7 @@ #endif #include +#include #include "gcenv.h" #include "thread.h" @@ -415,14 +416,14 @@ int64_t ep_rt_aot_perf_counter_query (void) { STATIC_CONTRACT_NOTHROW; - return (int64_t)PalQueryPerformanceCounter(); + return minipal_hires_ticks(); } int64_t ep_rt_aot_perf_frequency_query (void) { STATIC_CONTRACT_NOTHROW; - return (int64_t)PalQueryPerformanceFrequency(); + return minipal_hires_tick_frequency(); } int64_t diff --git a/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp b/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp index 01d251c46fc071..0fc3881c53476e 100644 --- a/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp +++ b/src/coreclr/nativeaot/Runtime/eventpipeinternal.cpp @@ -13,6 +13,7 @@ #include #include #include +#include "minipal/time.h" #ifdef FEATURE_PERFTRACING @@ -246,7 +247,7 @@ EXTERN_C UInt32_BOOL QCALLTYPE EventPipeInternal_GetSessionInfo(uint64_t session { pSessionInfo->StartTimeAsUTCFileTime = ep_session_get_session_start_time (pSession); pSessionInfo->StartTimeStamp = ep_session_get_session_start_timestamp(pSession); - pSessionInfo->TimeStampFrequency = PalQueryPerformanceFrequency(); + pSessionInfo->TimeStampFrequency = minipal_hires_tick_frequency(); retVal = true; } } diff --git a/src/coreclr/nativeaot/Runtime/startup.cpp b/src/coreclr/nativeaot/Runtime/startup.cpp index c53c99d8b73159..78c6429944df78 100644 --- a/src/coreclr/nativeaot/Runtime/startup.cpp +++ b/src/coreclr/nativeaot/Runtime/startup.cpp @@ -27,6 +27,7 @@ #include "RestrictedCallouts.h" #include "yieldprocessornormalized.h" #include +#include #ifdef FEATURE_PERFTRACING #include "EventPipeInterface.h" @@ -208,7 +209,7 @@ bool InitGSCookie() #endif // REVIEW: Need something better for PAL... - GSCookie val = (GSCookie)PalGetTickCount64(); + GSCookie val = (GSCookie)minipal_lowres_ticks(); #ifdef _DEBUG // In _DEBUG, always use the same value to make it easier to search for the cookie diff --git a/src/coreclr/nativeaot/Runtime/stressLog.cpp b/src/coreclr/nativeaot/Runtime/stressLog.cpp index c1461cd284de88..6c626eeef5a5dd 100644 --- a/src/coreclr/nativeaot/Runtime/stressLog.cpp +++ b/src/coreclr/nativeaot/Runtime/stressLog.cpp @@ -29,6 +29,7 @@ #include "threadstore.inl" #include "thread.inl" #include "volatile.h" +#include "minipal/time.h" #ifdef STRESS_LOG @@ -63,7 +64,7 @@ uint64_t getTimeStamp() #else // HOST_X86 uint64_t getTimeStamp() { - return PalQueryPerformanceCounter(); + return (uint64_t)minipal_hires_ticks(); } #endif // HOST_X86 else @@ -74,7 +75,7 @@ uint64_t getTimeStamp() */ uint64_t getTickFrequency() { - return PalQueryPerformanceFrequency(); + return (uint64_t)minipal_hires_tick_frequency(); } #endif // DACCESS_COMPILE diff --git a/src/coreclr/nativeaot/Runtime/thread.cpp b/src/coreclr/nativeaot/Runtime/thread.cpp index 0f269f23cbd58f..d4ed62a1881c5a 100644 --- a/src/coreclr/nativeaot/Runtime/thread.cpp +++ b/src/coreclr/nativeaot/Runtime/thread.cpp @@ -30,6 +30,7 @@ #include "RhConfig.h" #include "GcEnum.h" #include "NativeContext.h" +#include "minipal/time.h" #ifndef DACCESS_COMPILE @@ -40,7 +41,7 @@ static Thread* g_RuntimeInitializingThread; ee_alloc_context::PerThreadRandom::PerThreadRandom() { - minipal_xoshiro128pp_init(&random_state, (uint32_t)PalGetTickCount64()); + minipal_xoshiro128pp_init(&random_state, (uint32_t)minipal_lowres_ticks()); } thread_local ee_alloc_context::PerThreadRandom ee_alloc_context::t_random = PerThreadRandom(); diff --git a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp index a928e7018da25f..a790e83ad258bf 100644 --- a/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp +++ b/src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp @@ -730,15 +730,6 @@ REDHAWK_PALEXPORT bool REDHAWK_PALAPI PalStartEventPipeHelperThread(_In_ Backgro return PalStartBackgroundWork(callback, pCallbackContext, UInt32_FALSE); } -// Returns a 64-bit tick count with a millisecond resolution. It tries its best -// to return monotonically increasing counts and avoid being affected by changes -// to the system clock (either due to drift or due to explicit changes to system -// time). -REDHAWK_PALEXPORT uint64_t REDHAWK_PALAPI PalGetTickCount64() -{ - return GCToOSInterface::GetLowPrecisionTimeStamp(); -} - REDHAWK_PALEXPORT HANDLE REDHAWK_PALAPI PalGetModuleHandleFromPointer(_In_ void* pointer) { HANDLE moduleHandle = NULL; @@ -1207,16 +1198,6 @@ extern "C" void GetSystemTimeAsFileTime(FILETIME *lpSystemTimeAsFileTime) lpSystemTimeAsFileTime->dwHighDateTime = (uint32_t)(result >> 32); } -extern "C" uint64_t PalQueryPerformanceCounter() -{ - return GCToOSInterface::QueryPerformanceCounter(); -} - -extern "C" uint64_t PalQueryPerformanceFrequency() -{ - return GCToOSInterface::QueryPerformanceFrequency(); -} - extern "C" uint64_t PalGetCurrentOSThreadId() { return (uint64_t)minipal_get_current_thread_id(); diff --git a/src/coreclr/nativeaot/Runtime/unix/config.h.in b/src/coreclr/nativeaot/Runtime/unix/config.h.in index d5505b760c1f6f..3a5e1ef87b5dc3 100644 --- a/src/coreclr/nativeaot/Runtime/unix/config.h.in +++ b/src/coreclr/nativeaot/Runtime/unix/config.h.in @@ -20,8 +20,6 @@ #cmakedefine01 HAVE_SIGINFO_T #cmakedefine01 HAVE_LWP_SELF -#cmakedefine01 HAVE_CLOCK_MONOTONIC -#cmakedefine01 HAVE_CLOCK_MONOTONIC_COARSE #cmakedefine01 HAVE_CLOCK_GETTIME_NSEC_NP #cmakedefine01 HAVE_SCHED_GETAFFINITY diff --git a/src/coreclr/nativeaot/Runtime/unix/configure.cmake b/src/coreclr/nativeaot/Runtime/unix/configure.cmake index 39ce650e54a6d9..7cd0bf8ef7542e 100644 --- a/src/coreclr/nativeaot/Runtime/unix/configure.cmake +++ b/src/coreclr/nativeaot/Runtime/unix/configure.cmake @@ -59,34 +59,6 @@ int main(int argc, char **argv) return (int)_lwp_self(); }" HAVE_LWP_SELF) -check_cxx_source_runs(" -#include -#include -#include - -int main() -{ - int ret; - struct timespec ts; - ret = clock_gettime(CLOCK_MONOTONIC, &ts); - - exit(ret); -}" HAVE_CLOCK_MONOTONIC) - -check_cxx_source_runs(" -#include -#include -#include - -int main() -{ - int ret; - struct timespec ts; - ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); - - exit(ret); -}" HAVE_CLOCK_MONOTONIC_COARSE) - check_cxx_source_compiles(" #include diff --git a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkCommon.cpp b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkCommon.cpp index a805762b462166..801e1eab66d28c 100644 --- a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkCommon.cpp +++ b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkCommon.cpp @@ -102,8 +102,3 @@ REDHAWK_PALEXPORT int32_t PalGetModuleFileName(_Out_ const TCHAR** pModuleNameOu *pModuleNameOut = NULL; return 0; } - -REDHAWK_PALEXPORT uint64_t REDHAWK_PALAPI PalGetTickCount64() -{ - return GetTickCount64(); -} diff --git a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp index 0b8b0cb6400325..fbab660b11f6f3 100644 --- a/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp +++ b/src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp @@ -205,16 +205,6 @@ REDHAWK_PALEXPORT bool REDHAWK_PALAPI PalInit() return true; } -extern "C" uint64_t PalQueryPerformanceCounter() -{ - return GCToOSInterface::QueryPerformanceCounter(); -} - -extern "C" uint64_t PalQueryPerformanceFrequency() -{ - return GCToOSInterface::QueryPerformanceFrequency(); -} - extern "C" uint64_t PalGetCurrentOSThreadId() { return GetCurrentThreadId(); diff --git a/src/coreclr/nativeaot/Runtime/yieldprocessornormalized.cpp b/src/coreclr/nativeaot/Runtime/yieldprocessornormalized.cpp index efaf4e8bb20704..ae62fba4cb96d5 100644 --- a/src/coreclr/nativeaot/Runtime/yieldprocessornormalized.cpp +++ b/src/coreclr/nativeaot/Runtime/yieldprocessornormalized.cpp @@ -14,6 +14,7 @@ #include "slist.h" #include "volatile.h" #include "yieldprocessornormalized.h" +#include "minipal/time.h" #include "../../utilcode/yieldprocessornormalized.cpp" diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj index f687c6bb354546..251d8bfa97ecf6 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System.Private.CoreLib.csproj @@ -281,9 +281,6 @@ Interop\Windows\OleAut32\Interop.VariantClear.cs - - Interop\Windows\Kernel32\Interop.GetTickCount64.cs - Interop\Windows\Kernel32\Interop.DynamicLoad.cs diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Environment.NativeAot.Unix.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Environment.NativeAot.Unix.cs index 98cb7225171172..f437f3a17cf027 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Environment.NativeAot.Unix.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Environment.NativeAot.Unix.cs @@ -9,8 +9,6 @@ namespace System { public static partial class Environment { - public static long TickCount64 => (long)RuntimeImports.RhpGetTickCount64(); - [DoesNotReturn] private static void ExitRaw() => Interop.Sys.Exit(s_latchedExitCode); } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Environment.NativeAot.Windows.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Environment.NativeAot.Windows.cs index 9aaa5980fc68db..0c47251b931e92 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Environment.NativeAot.Windows.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Environment.NativeAot.Windows.cs @@ -7,8 +7,6 @@ namespace System { public static partial class Environment { - public static long TickCount64 => (long)Interop.Kernel32.GetTickCount64(); - [DoesNotReturn] private static void ExitRaw() => Interop.Kernel32.ExitProcess(s_latchedExitCode); } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Environment.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Environment.NativeAot.cs index 777e4e99dba78e..20a3c46aeb5748 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Environment.NativeAot.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Environment.NativeAot.cs @@ -55,7 +55,5 @@ internal static void ShutdownCore() AppContext.OnProcessExit(); #endif } - - public static int TickCount => (int)TickCount64; } } diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs index 64483dd95fa41e..fcd46519f2de4b 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -40,10 +40,6 @@ internal static partial class RuntimeImports [RuntimeImport(RuntimeLibrary, "RhGetRuntimeVersion")] internal static extern unsafe byte* RhGetRuntimeVersion(out int cbLength); - [LibraryImport(RuntimeLibrary)] - [SuppressGCTransition] - internal static partial ulong RhpGetTickCount64(); - [LibraryImport(RuntimeLibrary)] internal static partial IntPtr RhpGetCurrentThread(); diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 01af26fce1a6cb..9cd5c81aa591f6 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -3145,30 +3145,6 @@ RaiseFailFastException( IN PCONTEXT pContextRecord, IN DWORD dwFlags); -PALIMPORT -DWORD -PALAPI -GetTickCount(); - -PALIMPORT -ULONGLONG -PALAPI -GetTickCount64(); - -PALIMPORT -BOOL -PALAPI -QueryPerformanceCounter( - OUT LARGE_INTEGER *lpPerformanceCount - ); - -PALIMPORT -BOOL -PALAPI -QueryPerformanceFrequency( - OUT LARGE_INTEGER *lpFrequency - ); - PALIMPORT BOOL PALAPI diff --git a/src/coreclr/pal/src/config.h.in b/src/coreclr/pal/src/config.h.in index d0197a724a4202..83a6e3be90e468 100644 --- a/src/coreclr/pal/src/config.h.in +++ b/src/coreclr/pal/src/config.h.in @@ -90,9 +90,6 @@ #cmakedefine01 HAVE_SCHED_GET_PRIORITY #cmakedefine01 HAVE_WORKING_GETTIMEOFDAY #cmakedefine01 HAVE_WORKING_CLOCK_GETTIME -#cmakedefine01 HAVE_CLOCK_MONOTONIC -#cmakedefine01 HAVE_CLOCK_MONOTONIC_COARSE -#cmakedefine01 HAVE_CLOCK_GETTIME_NSEC_NP #cmakedefine01 HAVE_CLOCK_THREAD_CPUTIME #cmakedefine01 HAVE_PTHREAD_CONDATTR_SETCLOCK #cmakedefine01 MMAP_ANON_IGNORES_PROTECTION @@ -118,8 +115,6 @@ #cmakedefine01 SET_SCHEDPARAM_NEEDS_PRIVS #define CHECK_TRACE_SPECIFIERS 0 -#define HAVE_GETHRTIME 0 -#define HAVE_READ_REAL_TIME 0 #define OPEN64_IS_USED_INSTEAD_OF_OPEN 0 #define PAL_IGNORE_NORMAL_THREAD_PRIORITY 0 #define SELF_SUSPEND_FAILS_WITH_NATIVE_SUSPENSION 0 diff --git a/src/coreclr/pal/src/configure.cmake b/src/coreclr/pal/src/configure.cmake index 122e1707bad0ff..1833e46fbf5d74 100644 --- a/src/coreclr/pal/src/configure.cmake +++ b/src/coreclr/pal/src/configure.cmake @@ -394,33 +394,6 @@ check_cxx_source_runs(" #include #include -int main() -{ - int ret; - struct timespec ts; - ret = clock_gettime(CLOCK_MONOTONIC_COARSE, &ts); - - exit(ret); -}" HAVE_CLOCK_MONOTONIC_COARSE) -set(CMAKE_REQUIRED_LIBRARIES) - -check_cxx_source_runs(" -#include -#include - -int main() -{ - int ret; - ret = clock_gettime_nsec_np(CLOCK_UPTIME_RAW); - exit((ret == 0) ? 1 : 0); -}" HAVE_CLOCK_GETTIME_NSEC_NP) - -set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_RT_LIBS}) -check_cxx_source_runs(" -#include -#include -#include - int main() { int ret; diff --git a/src/coreclr/pal/src/misc/perfjitdump.cpp b/src/coreclr/pal/src/misc/perfjitdump.cpp index 9040e13dadfd00..67dc6cbbdd1318 100644 --- a/src/coreclr/pal/src/misc/perfjitdump.cpp +++ b/src/coreclr/pal/src/misc/perfjitdump.cpp @@ -26,6 +26,7 @@ #include #include #include +#include "minipal/time.h" #include "../inc/llvm/ELF.h" @@ -90,9 +91,7 @@ namespace return static_cast(__rdtsc()); } #endif - LARGE_INTEGER result; - QueryPerformanceCounter(&result); - return result.QuadPart; + return (uint64_t)minipal_hires_ticks(); } @@ -190,9 +189,7 @@ struct PerfJitDumpState // will return a direct nanosecond value. If this isn't true, // then some other method will need to be used to implement GetTimeStampNS. // Validate this is true once in Start here. - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - if (freq.QuadPart != tccSecondsToNanoSeconds) + if (minipal_hires_tick_frequency() != tccSecondsToNanoSeconds) { _ASSERTE(!"QueryPerformanceFrequency does not return tccSecondsToNanoSeconds. Implement JITDUMP GetTimeStampNS directly for this platform.\n"); FatalError(); diff --git a/src/coreclr/pal/src/misc/time.cpp b/src/coreclr/pal/src/misc/time.cpp index 2774cb7f125b75..a7876453a6addf 100644 --- a/src/coreclr/pal/src/misc/time.cpp +++ b/src/coreclr/pal/src/misc/time.cpp @@ -118,109 +118,6 @@ GetSystemTime( PERF_EXIT(GetSystemTime); } -/*++ -Function: - GetTickCount - -The GetTickCount function retrieves the number of milliseconds that -have elapsed since the system was started. It is limited to the -resolution of the system timer. To obtain the system timer resolution, -use the GetSystemTimeAdjustment function. - -Parameters - -This function has no parameters. - -Return Values - -The return value is the number of milliseconds that have elapsed since -the system was started. - -In the PAL implementation the return value is the elapsed time since -the start of the epoch. - ---*/ -DWORD -PALAPI -GetTickCount( - VOID) -{ - DWORD retval = 0; - PERF_ENTRY(GetTickCount); - ENTRY("GetTickCount ()\n"); - - // Get the 64-bit count from GetTickCount64 and truncate the results. - retval = (DWORD) GetTickCount64(); - - LOGEXIT("GetTickCount returns DWORD %u\n", retval); - PERF_EXIT(GetTickCount); - return retval; -} - -BOOL -PALAPI -QueryPerformanceCounter( - OUT LARGE_INTEGER *lpPerformanceCount - ) -{ - BOOL retval = TRUE; - PERF_ENTRY(QueryPerformanceCounter); - ENTRY("QueryPerformanceCounter()\n"); - -#if HAVE_CLOCK_GETTIME_NSEC_NP - lpPerformanceCount->QuadPart = (LONGLONG)clock_gettime_nsec_np(CLOCK_UPTIME_RAW); -#elif HAVE_CLOCK_MONOTONIC - struct timespec ts; - int result = clock_gettime(CLOCK_MONOTONIC, &ts); - - if (result != 0) - { - ASSERT("clock_gettime(CLOCK_MONOTONIC) failed: %d\n", result); - retval = FALSE; - } - else - { - lpPerformanceCount->QuadPart = - ((LONGLONG)(ts.tv_sec) * (LONGLONG)(tccSecondsToNanoSeconds)) + (LONGLONG)(ts.tv_nsec); - } -#else - #error "The PAL requires either mach_absolute_time() or clock_gettime(CLOCK_MONOTONIC) to be supported." -#endif - - LOGEXIT("QueryPerformanceCounter\n"); - PERF_EXIT(QueryPerformanceCounter); - return retval; -} - -BOOL -PALAPI -QueryPerformanceFrequency( - OUT LARGE_INTEGER *lpFrequency - ) -{ - BOOL retval = TRUE; - PERF_ENTRY(QueryPerformanceFrequency); - ENTRY("QueryPerformanceFrequency()\n"); - -#if HAVE_CLOCK_GETTIME_NSEC_NP - lpFrequency->QuadPart = (LONGLONG)(tccSecondsToNanoSeconds); -#elif HAVE_CLOCK_MONOTONIC - // 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. - - lpFrequency->QuadPart = (LONGLONG)(tccSecondsToNanoSeconds); -#else - #error "The PAL requires either mach_absolute_time() or clock_gettime(CLOCK_MONOTONIC) to be supported." -#endif - - LOGEXIT("QueryPerformanceFrequency\n"); - PERF_EXIT(QueryPerformanceFrequency); - return retval; -} - /*++ Function: QueryThreadCycleTime @@ -259,58 +156,6 @@ QueryThreadCycleTime( return retval; } -/*++ -Function: - GetTickCount64 - -Returns a 64-bit tick count with a millisecond resolution. It tries its best -to return monotonically increasing counts and avoid being affected by changes -to the system clock (either due to drift or due to explicit changes to system -time). ---*/ -PALAPI -ULONGLONG -GetTickCount64() -{ - LONGLONG retval = 0; - -#if HAVE_CLOCK_GETTIME_NSEC_NP - return (LONGLONG)clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / (LONGLONG)(tccMillieSecondsToNanoSeconds); -#elif HAVE_CLOCK_MONOTONIC || HAVE_CLOCK_MONOTONIC_COARSE - struct timespec ts; - -#if HAVE_CLOCK_MONOTONIC_COARSE - // CLOCK_MONOTONIC_COARSE has enough precision for GetTickCount but - // doesn't have the same overhead as CLOCK_MONOTONIC. This allows - // overall higher throughput. See dotnet/coreclr#2257 for more details. - - const clockid_t clockType = CLOCK_MONOTONIC_COARSE; -#else - const clockid_t clockType = CLOCK_MONOTONIC; -#endif - - int result = clock_gettime(clockType, &ts); - - if (result != 0) - { -#if HAVE_CLOCK_MONOTONIC_COARSE - ASSERT("clock_gettime(CLOCK_MONOTONIC_COARSE) failed: %d\n", result); -#else - ASSERT("clock_gettime(CLOCK_MONOTONIC) failed: %d\n", result); -#endif - retval = FALSE; - } - else - { - retval = ((LONGLONG)(ts.tv_sec) * (LONGLONG)(tccSecondsToMillieSeconds)) + ((LONGLONG)(ts.tv_nsec) / (LONGLONG)(tccMillieSecondsToNanoSeconds)); - } -#else - #error "The PAL requires either mach_absolute_time() or clock_gettime(CLOCK_MONOTONIC) to be supported." -#endif - - return (ULONGLONG)(retval); -} - /*++ Function: PAL_nanosleep diff --git a/src/coreclr/pal/src/synchobj/mutex.cpp b/src/coreclr/pal/src/synchobj/mutex.cpp index a259f76e0192c6..f23254612c555c 100644 --- a/src/coreclr/pal/src/synchobj/mutex.cpp +++ b/src/coreclr/pal/src/synchobj/mutex.cpp @@ -33,6 +33,7 @@ SET_DEFAULT_DEBUG_CHANNEL(SYNC); // some headers have code with asserts, so do t #include #include #include +#include "minipal/time.h" using namespace CorUnix; @@ -1497,7 +1498,7 @@ MutexTryAcquireLockResult NamedMutexProcessData::TryAcquireLock(SharedMemorySyst DWORD startTime = 0; if (timeoutMilliseconds != static_cast(-1) && timeoutMilliseconds != 0) { - startTime = GetTickCount(); + startTime = (DWORD)minipal_lowres_ticks(); } // Acquire the process lock. A file lock can only be acquired once per file descriptor, so to synchronize the threads of @@ -1626,7 +1627,7 @@ MutexTryAcquireLockResult NamedMutexProcessData::TryAcquireLock(SharedMemorySyst // Poll for the file lock do { - DWORD elapsedMilliseconds = GetTickCount() - startTime; + DWORD elapsedMilliseconds = (DWORD)minipal_lowres_ticks() - startTime; if (elapsedMilliseconds >= timeoutMilliseconds) { return MutexTryAcquireLockResult::TimedOut; diff --git a/src/coreclr/pal/tests/palsuite/CMakeLists.txt b/src/coreclr/pal/tests/palsuite/CMakeLists.txt index 93b9c0070ba18b..29aaeeb274f2f9 100644 --- a/src/coreclr/pal/tests/palsuite/CMakeLists.txt +++ b/src/coreclr/pal/tests/palsuite/CMakeLists.txt @@ -355,7 +355,6 @@ add_executable_clr(paltests miscellaneous/GetEnvironmentVariableW/test6/test6.cpp miscellaneous/GetLastError/test1/test.cpp miscellaneous/GetSystemInfo/test1/test.cpp - miscellaneous/GetTickCount/test1/test.cpp miscellaneous/InterlockedCompareExchange/test1/test.cpp miscellaneous/InterlockedCompareExchange/test2/test.cpp miscellaneous/InterlockedCompareExchange64/test1/test.cpp @@ -378,8 +377,6 @@ add_executable_clr(paltests #miscellaneous/IsBadWritePtr/test1/test.cpp #miscellaneous/IsBadWritePtr/test2/test2.cpp #miscellaneous/IsBadWritePtr/test3/test3.cpp - miscellaneous/queryperformancecounter/test1/test1.cpp - miscellaneous/queryperformancefrequency/test1/test1.cpp miscellaneous/SetEnvironmentVariableA/test1/test1.cpp miscellaneous/SetEnvironmentVariableA/test2/test2.cpp miscellaneous/SetEnvironmentVariableA/test3/test3.cpp diff --git a/src/coreclr/pal/tests/palsuite/common/palsuite.cpp b/src/coreclr/pal/tests/palsuite/common/palsuite.cpp index 34972558853c4f..030d8cc13cd6d6 100644 --- a/src/coreclr/pal/tests/palsuite/common/palsuite.cpp +++ b/src/coreclr/pal/tests/palsuite/common/palsuite.cpp @@ -12,6 +12,7 @@ #include "palsuite.h" +#include "minipal/time.h" const char* szTextFile = "text.txt"; @@ -53,13 +54,7 @@ char* convertC(const WCHAR * wString) UINT64 GetHighPrecisionTimeStamp(LARGE_INTEGER performanceFrequency) { - LARGE_INTEGER ts; - if (!QueryPerformanceCounter(&ts)) - { - Fail("ERROR: Unable to query performance counter!\n"); - } - - return ts.QuadPart / (performanceFrequency.QuadPart / 1000); + return (UINT64)minipal_hires_ticks(); } static const char* rgchPathDelim = "/"; @@ -223,4 +218,4 @@ DeleteFileW( } return FALSE; -} \ No newline at end of file +} diff --git a/src/coreclr/pal/tests/palsuite/common/palsuite.h b/src/coreclr/pal/tests/palsuite/common/palsuite.h index 9494daed71bebd..ed5766963533e8 100644 --- a/src/coreclr/pal/tests/palsuite/common/palsuite.h +++ b/src/coreclr/pal/tests/palsuite/common/palsuite.h @@ -25,6 +25,7 @@ typedef unsigned short char16_t; #include #include #include +#include #include #define PALTEST(testfunc, testname) \ diff --git a/src/coreclr/pal/tests/palsuite/compilableTests.txt b/src/coreclr/pal/tests/palsuite/compilableTests.txt index d9c36e4ab5d299..7883adf0809db7 100644 --- a/src/coreclr/pal/tests/palsuite/compilableTests.txt +++ b/src/coreclr/pal/tests/palsuite/compilableTests.txt @@ -271,7 +271,6 @@ miscellaneous/GetEnvironmentVariableW/test5/paltest_getenvironmentvariablew_test miscellaneous/GetEnvironmentVariableW/test6/paltest_getenvironmentvariablew_test6 miscellaneous/GetLastError/test1/paltest_getlasterror_test1 miscellaneous/GetSystemInfo/test1/paltest_getsysteminfo_test1 -miscellaneous/GetTickCount/test1/paltest_gettickcount_test1 miscellaneous/InterlockedCompareExchange/test1/paltest_interlockedcompareexchange_test1 miscellaneous/InterlockedCompareExchange/test2/paltest_interlockedcompareexchange_test2 miscellaneous/InterlockedCompareExchange64/test1/paltest_interlockedcompareexchange64_test1 @@ -289,8 +288,6 @@ miscellaneous/InterlockedIncrement/test1/paltest_interlockedincrement_test1 miscellaneous/InterlockedIncrement/test2/paltest_interlockedincrement_test2 miscellaneous/InterlockedIncrement64/test1/paltest_interlockedincrement64_test1 miscellaneous/InterlockedIncrement64/test2/paltest_interlockedincrement64_test2 -miscellaneous/queryperformancecounter/test1/paltest_queryperformancecounter_test1 -miscellaneous/queryperformancefrequency/test1/paltest_queryperformancefrequency_test1 miscellaneous/SetEnvironmentVariableA/test1/paltest_setenvironmentvariablea_test1 miscellaneous/SetEnvironmentVariableA/test2/paltest_setenvironmentvariablea_test2 miscellaneous/SetEnvironmentVariableA/test3/paltest_setenvironmentvariablea_test3 diff --git a/src/coreclr/pal/tests/palsuite/composite/object_management/event/nonshared/event.cpp b/src/coreclr/pal/tests/palsuite/composite/object_management/event/nonshared/event.cpp index bc521da91b3a15..fab380597d7386 100644 --- a/src/coreclr/pal/tests/palsuite/composite/object_management/event/nonshared/event.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/object_management/event/nonshared/event.cpp @@ -142,7 +142,7 @@ PALTEST(composite_object_management_event_nonshared_paltest_event_nonshared, "co } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); processStats.relationId = RELATION_ID; processStats.processId = USE_PROCESS_COUNT; @@ -308,7 +308,7 @@ void PALAPI Run_Thread_event_nonshared (LPVOID lpParam) Fail("Error while waiting for StartTest Event@ thread %d, RC is %d, Error is %d\n", Id, dwWaitResult, GetLastError()); } - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); for( i = 0; i < REPEAT_COUNT; i++ ) { diff --git a/src/coreclr/pal/tests/palsuite/composite/object_management/event/nonshared/main.cpp b/src/coreclr/pal/tests/palsuite/composite/object_management/event/nonshared/main.cpp index 115632a833f43b..65a82a38ca0885 100644 --- a/src/coreclr/pal/tests/palsuite/composite/object_management/event/nonshared/main.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/object_management/event/nonshared/main.cpp @@ -114,7 +114,7 @@ PALTEST(composite_object_management_event_nonshared_paltest_event_nonshared, "co } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); testStats.relationId = RELATION_ID; testStats.processCount = PROCESS_COUNT; testStats.threadCount = THREAD_COUNT; diff --git a/src/coreclr/pal/tests/palsuite/composite/object_management/event/shared/event.cpp b/src/coreclr/pal/tests/palsuite/composite/object_management/event/shared/event.cpp index 155d5e9bd9b452..26f528a3e80ff9 100644 --- a/src/coreclr/pal/tests/palsuite/composite/object_management/event/shared/event.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/object_management/event/shared/event.cpp @@ -156,7 +156,7 @@ PALTEST(composite_object_management_event_shared_paltest_event_shared, "composit } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); processStats.relationId = RELATION_ID; processStats.processId = USE_PROCESS_COUNT; @@ -321,7 +321,7 @@ void PALAPI Run_Thread_event_shared (LPVOID lpParam) testStatus = FAIL; } - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); for( i = 0; i < REPEAT_COUNT; i++ ) { diff --git a/src/coreclr/pal/tests/palsuite/composite/object_management/event/shared/main.cpp b/src/coreclr/pal/tests/palsuite/composite/object_management/event/shared/main.cpp index cce500d10cbf15..32287705cbb91d 100644 --- a/src/coreclr/pal/tests/palsuite/composite/object_management/event/shared/main.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/object_management/event/shared/main.cpp @@ -130,7 +130,7 @@ PALTEST(composite_object_management_event_shared_paltest_event_shared, "composit } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); testStats.relationId = RELATION_ID; testStats.processCount = PROCESS_COUNT; testStats.threadCount = THREAD_COUNT; diff --git a/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/nonshared/main.cpp b/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/nonshared/main.cpp index 4277e66e0821dc..3878df1fe9ef7b 100644 --- a/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/nonshared/main.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/nonshared/main.cpp @@ -115,7 +115,7 @@ PALTEST(composite_object_management_mutex_nonshared_paltest_mutex_nonshared, "co } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); testStats.relationId = RELATION_ID; testStats.processCount = PROCESS_COUNT; testStats.threadCount = THREAD_COUNT; diff --git a/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/nonshared/mutex.cpp b/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/nonshared/mutex.cpp index a3503dc4702da2..d22381c288313d 100644 --- a/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/nonshared/mutex.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/nonshared/mutex.cpp @@ -135,7 +135,7 @@ PALTEST(composite_object_management_mutex_nonshared_paltest_mutex_nonshared, "co } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); processStats.relationId = RELATION_ID; processStats.processId = USE_PROCESS_COUNT; @@ -289,7 +289,7 @@ void PALAPI Run_Thread_mutex_nonshared (LPVOID lpParam) testStatus = FAIL; } - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); for( i = 0; i < REPEAT_COUNT; i++ ) { diff --git a/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/shared/main.cpp b/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/shared/main.cpp index 3790785d065126..c42b95d9f5b381 100644 --- a/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/shared/main.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/shared/main.cpp @@ -132,7 +132,7 @@ PALTEST(composite_object_management_mutex_shared_paltest_mutex_shared, "composit } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); testStats.relationId = RELATION_ID; testStats.processCount = PROCESS_COUNT; testStats.threadCount = THREAD_COUNT; diff --git a/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/shared/mutex.cpp b/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/shared/mutex.cpp index 51400a99564ed7..8bc6645c04f4f1 100644 --- a/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/shared/mutex.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/object_management/mutex/shared/mutex.cpp @@ -156,7 +156,7 @@ PALTEST(composite_object_management_mutex_shared_paltest_mutex_shared, "composit } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); processStats.relationId = RELATION_ID; processStats.processId = USE_PROCESS_COUNT; @@ -306,7 +306,7 @@ void PALAPI Run_Thread_mutex_shared (LPVOID lpParam) testStatus = FAIL; } - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); for( i = 0; i < REPEAT_COUNT; i++ ) { diff --git a/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/nonshared/main.cpp b/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/nonshared/main.cpp index 99b0b2b2a55377..3075b29c2a6669 100644 --- a/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/nonshared/main.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/nonshared/main.cpp @@ -115,7 +115,7 @@ PALTEST(composite_object_management_semaphore_nonshared_paltest_semaphore_nonsha } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); testStats.relationId = RELATION_ID; testStats.processCount = PROCESS_COUNT; testStats.threadCount = THREAD_COUNT; diff --git a/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/nonshared/semaphore.cpp b/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/nonshared/semaphore.cpp index b37c1218d6431d..89616ad01d5a01 100644 --- a/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/nonshared/semaphore.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/nonshared/semaphore.cpp @@ -143,7 +143,7 @@ PALTEST(composite_object_management_semaphore_nonshared_paltest_semaphore_nonsha } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); processStats.relationId = RELATION_ID; processStats.processId = USE_PROCESS_COUNT; @@ -294,7 +294,7 @@ void PALAPI Run_Thread_semaphore_nonshared (LPVOID lpParam) Fail("Error while waiting for StartTest Event@ thread %d, RC is %d, Error is %d\n", Id, dwWaitResult, GetLastError()); } - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); for( i = 0; i < REPEAT_COUNT; i++ ) { diff --git a/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/shared/main.cpp b/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/shared/main.cpp index df1ea1f7bea361..e96e77abda1248 100644 --- a/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/shared/main.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/shared/main.cpp @@ -141,7 +141,7 @@ us anything over what we already have." } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); testStats.relationId = RELATION_ID; testStats.processCount = PROCESS_COUNT; testStats.threadCount = THREAD_COUNT; diff --git a/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/shared/semaphore.cpp b/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/shared/semaphore.cpp index bcad3c3ada4215..0fec6fef7e971c 100644 --- a/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/shared/semaphore.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/object_management/semaphore/shared/semaphore.cpp @@ -155,7 +155,7 @@ PALTEST(composite_object_management_semaphore_shared_paltest_semaphore_shared, " } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); processStats.relationId = RELATION_ID; processStats.processId = USE_PROCESS_COUNT; @@ -306,7 +306,7 @@ void PALAPI Run_Thread_semaphore_shared (LPVOID lpParam) Fail("Error while waiting for StartTest Event@ thread %d, RC is %d, Error is %d\n", Id, dwWaitResult, GetLastError()); } - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); for( i = 0; i < REPEAT_COUNT; i++ ) { diff --git a/src/coreclr/pal/tests/palsuite/composite/synchronization/criticalsection/criticalsection.cpp b/src/coreclr/pal/tests/palsuite/composite/synchronization/criticalsection/criticalsection.cpp index 80dd3935d06217..5935e46f028fae 100644 --- a/src/coreclr/pal/tests/palsuite/composite/synchronization/criticalsection/criticalsection.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/synchronization/criticalsection/criticalsection.cpp @@ -176,7 +176,7 @@ enterandleavecs( LPVOID lpParam ) } //Collect operation start time - dwStart = GetTickCount(); + dwStart = (DWORD)minipal_lowres_ticks(); //Operation starts loopcount times for(i = 0; i < loopcount; i++) @@ -193,7 +193,7 @@ enterandleavecs( LPVOID lpParam ) stats.operationsTotal++; } //collect operation end time - stats.operationTime = GetTickCount() - dwStart; + stats.operationTime = (DWORD)minipal_lowres_ticks() - dwStart; /*Trace("\n\n\n\nOperation Time %d\n", stats.operationTime); Trace("Operation Passed %d\n", stats.operationsPassed); @@ -258,7 +258,7 @@ processStats.processId = USE_PROCESS_COUNT; processStats.relationId = RELATION_ID; //Will change later //Start Process Time Capture -dwStart = GetTickCount(); +dwStart = (DWORD)minipal_lowres_ticks(); //setup file for thread result collection statisticsSize = sizeof(struct statistics); @@ -322,7 +322,7 @@ if ( WAIT_OBJECT_0 != WaitForMultipleObjects (THREAD_COUNT,hThread,TRUE, INFINIT //Get the end time of the process -processStats.operationTime = GetTickCount() - dwStart; +processStats.operationTime = (DWORD)minipal_lowres_ticks() - dwStart; //Write Process Result Contents to File if(hProcessFile!= NULL) diff --git a/src/coreclr/pal/tests/palsuite/composite/synchronization/criticalsection/mainWrapper.cpp b/src/coreclr/pal/tests/palsuite/composite/synchronization/criticalsection/mainWrapper.cpp index 529dddb3065e2b..99a1d0c5dad7f3 100644 --- a/src/coreclr/pal/tests/palsuite/composite/synchronization/criticalsection/mainWrapper.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/synchronization/criticalsection/mainWrapper.cpp @@ -134,7 +134,7 @@ if(hFile == NULL) } //Start Process Time Capture -dwStart = GetTickCount(); +dwStart = (DWORD)minipal_lowres_ticks(); for( i = 0; i < USE_PROCESS_COUNT; i++ ) { @@ -216,7 +216,7 @@ for( i = 0; i < USE_PROCESS_COUNT; i++ ) } //Get the end time of the process -appStats.operationTime = GetTickCount() - dwStart; +appStats.operationTime = (DWORD)minipal_lowres_ticks() - dwStart; if( testReturnCode == PASS) { diff --git a/src/coreclr/pal/tests/palsuite/composite/wfmo/main.cpp b/src/coreclr/pal/tests/palsuite/composite/wfmo/main.cpp index 0e0684e5f4f07e..e12cb5d596b88e 100644 --- a/src/coreclr/pal/tests/palsuite/composite/wfmo/main.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/wfmo/main.cpp @@ -127,7 +127,7 @@ PALTEST(composite_wfmo_paltest_composite_wfmo, "composite/wfmo/paltest_composite } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); testStats.relationId = 0; testStats.relationId = RELATION_ID; testStats.processCount = PROCESS_COUNT; diff --git a/src/coreclr/pal/tests/palsuite/composite/wfmo/mutex.cpp b/src/coreclr/pal/tests/palsuite/composite/wfmo/mutex.cpp index 82f59880c404de..ed5de0fafd16ea 100644 --- a/src/coreclr/pal/tests/palsuite/composite/wfmo/mutex.cpp +++ b/src/coreclr/pal/tests/palsuite/composite/wfmo/mutex.cpp @@ -146,7 +146,7 @@ PALTEST(composite_wfmo_paltest_composite_wfmo, "composite/wfmo/paltest_composite } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); processStats.relationId = RELATION_ID; processStats.processId = USE_PROCESS_COUNT; @@ -306,7 +306,7 @@ void PALAPI Run_Thread_composite_wfmo (LPVOID lpParam) } /* Register the start time */ - dwStartTime = GetTickCount(); + dwStartTime = (DWORD)minipal_lowres_ticks(); /* Run the tests repeat count times */ for( i = 0; i < REPEAT_COUNT; i++ ) diff --git a/src/coreclr/pal/tests/palsuite/issues.targets b/src/coreclr/pal/tests/palsuite/issues.targets index 67b5df72eeb336..a4381220bb96a0 100644 --- a/src/coreclr/pal/tests/palsuite/issues.targets +++ b/src/coreclr/pal/tests/palsuite/issues.targets @@ -18,10 +18,4 @@ - - - https://github.com/dotnet/runtime/issues/7639 - - - diff --git a/src/coreclr/pal/tests/palsuite/miscellaneous/GetTickCount/test1/test.cpp b/src/coreclr/pal/tests/palsuite/miscellaneous/GetTickCount/test1/test.cpp deleted file mode 100644 index f783ff878ceb8f..00000000000000 --- a/src/coreclr/pal/tests/palsuite/miscellaneous/GetTickCount/test1/test.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================ -** -** Source: -** -** Source : test1.c -** -** Purpose: Test for GetTickCount() function -** -** -**=========================================================*/ - -#include - -PALTEST(miscellaneous_GetTickCount_test1_paltest_gettickcount_test1, "miscellaneous/GetTickCount/test1/paltest_gettickcount_test1") -{ - - DWORD FirstCount = 0; - DWORD SecondCount = 0; - - /* - * Initialize the PAL and return FAILURE if this fails - */ - - if(0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - /* Grab a FirstCount, then loop for a bit to make the clock increase */ - FirstCount = GetTickCount(); - - /* Make sure some time passes */ - Sleep(60); //Since the get tick count is accurate within 55 milliseconds. - - /* Get a second count */ - SecondCount = GetTickCount(); - - /* Make sure the second one is bigger than the first. - This isn't the best test, but it at least shows that it's returning a - DWORD which is increasing. - */ - - if(FirstCount >= SecondCount) - { - Fail("ERROR: The first time (%d) was greater/equal than the second time " - " (%d). The tick count should have increased.\n", - FirstCount,SecondCount); - } - - PAL_Terminate(); - return PASS; -} - - - diff --git a/src/coreclr/pal/tests/palsuite/miscellaneous/queryperformancecounter/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/miscellaneous/queryperformancecounter/test1/test1.cpp deleted file mode 100644 index d14fa2fa2bb226..00000000000000 --- a/src/coreclr/pal/tests/palsuite/miscellaneous/queryperformancecounter/test1/test1.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================ -** -** Source: test1.c -** -** Purpose: Test for QueryPerformanceCounter function -** -** -**=========================================================*/ - -/* Depends on: QueryPerformanceFrequency. */ - -#include - - -PALTEST(miscellaneous_queryperformancecounter_test1_paltest_queryperformancecounter_test1, "miscellaneous/queryperformancecounter/test1/paltest_queryperformancecounter_test1") -{ - /* Milliseconds of error which are acceptable Function execution time, etc. - FreeBSD has a "standard" resolution of 50ms for waiting operations, so we - must take that into account as well */ - DWORD AcceptableTimeError = 15; - - int i; - int NumIterations = 100; - DWORD AvgTimeDiff; - DWORD TimeDiff[100]; - DWORD TotalTimeDiff = 0; - DWORD SleepInterval = 50; - LARGE_INTEGER StartTime; - LARGE_INTEGER EndTime; - LARGE_INTEGER Freq; - - /* Initialize the PAL. - */ - - if(0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - /* Get the frequency of the High-Performance Counter, - * in order to convert counter time to milliseconds. - */ - if (!QueryPerformanceFrequency(&Freq)) - { - Fail("ERROR:%u:Unable to retrieve the frequency of the " - "high-resolution performance counter.\n", - GetLastError()); - } - - /* Perform this set of sleep timings a number of times. - */ - for(i=0; i < NumIterations; i++) - { - - /* Get the current counter value. - */ - if (!QueryPerformanceCounter(&StartTime)) - { - Fail("ERROR:%u:Unable to retrieve the current value of the " - "high-resolution performance counter.\n", - GetLastError()); - } - - /* Sleep a predetermined interval. - */ - Sleep(SleepInterval); - - /* Get the new current counter value. - */ - if (!QueryPerformanceCounter(&EndTime)) - { - Fail("ERROR:%u:Unable to retrieve the current value of the " - "high-resolution performance counter.\n", - GetLastError()); - } - - /* Determine elapsed time, in milliseconds. Compare the elapsed time - * with the sleep interval, and add to counter. - */ - TimeDiff[i] = (DWORD)(((EndTime.QuadPart - StartTime.QuadPart)*1000)/ - (Freq.QuadPart)); - TotalTimeDiff += TimeDiff[i] - SleepInterval; - - } - - /* Verify that the average of the difference between the performance - * counter and the sleep interval is within our acceptable range. - */ - AvgTimeDiff = TotalTimeDiff / NumIterations; - if (AvgTimeDiff > AcceptableTimeError) - { - Fail("ERROR: average diff %u acceptable %u.\n", - AvgTimeDiff, - AcceptableTimeError); - } - - /* Terminate the PAL. - */ - PAL_Terminate(); - return PASS; -} - - diff --git a/src/coreclr/pal/tests/palsuite/miscellaneous/queryperformancefrequency/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/miscellaneous/queryperformancefrequency/test1/test1.cpp deleted file mode 100644 index 3e370ddafb10f6..00000000000000 --- a/src/coreclr/pal/tests/palsuite/miscellaneous/queryperformancefrequency/test1/test1.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -/*============================================================ -** -** Source: test1.c -** -** Purpose: Test for QueryPerformanceFrequency function -** -** -**=========================================================*/ - -#include - -PALTEST(miscellaneous_queryperformancefrequency_test1_paltest_queryperformancefrequency_test1, "miscellaneous/queryperformancefrequency/test1/paltest_queryperformancefrequency_test1") -{ - - LARGE_INTEGER Freq; - - /* Initialize the PAL. - */ - - if(0 != (PAL_Initialize(argc, argv))) - { - return FAIL; - } - - /* Check the return value of the performance - * frequency, a value of zero indicates that - * either the call has failed or the - * high-resolution performance counter is not - * installed. - */ - if (!QueryPerformanceFrequency(&Freq)) - { - - Fail("ERROR:%u:Unable to retrieve the frequency of the " - "high-resolution performance counter.\n", - GetLastError()); - } - - - /* Check the return value the frequency the - * value should be non-zero. - */ - if (Freq.QuadPart == 0) - { - - Fail("ERROR: The frequency has been determined to be 0 " - "the frequency should be non-zero.\n"); - - } - - /* Terminate the PAL. - */ - PAL_Terminate(); - return PASS; -} diff --git a/src/coreclr/pal/tests/palsuite/paltestlist.txt b/src/coreclr/pal/tests/palsuite/paltestlist.txt index c5d87fb07b4eec..202816002d2361 100644 --- a/src/coreclr/pal/tests/palsuite/paltestlist.txt +++ b/src/coreclr/pal/tests/palsuite/paltestlist.txt @@ -226,7 +226,6 @@ miscellaneous/GetEnvironmentVariableW/test5/paltest_getenvironmentvariablew_test miscellaneous/GetEnvironmentVariableW/test6/paltest_getenvironmentvariablew_test6 miscellaneous/GetLastError/test1/paltest_getlasterror_test1 miscellaneous/GetSystemInfo/test1/paltest_getsysteminfo_test1 -miscellaneous/GetTickCount/test1/paltest_gettickcount_test1 miscellaneous/InterlockedCompareExchange/test1/paltest_interlockedcompareexchange_test1 miscellaneous/InterlockedCompareExchange/test2/paltest_interlockedcompareexchange_test2 miscellaneous/InterlockedCompareExchange64/test1/paltest_interlockedcompareexchange64_test1 @@ -243,8 +242,6 @@ miscellaneous/InterlockedIncrement/test1/paltest_interlockedincrement_test1 miscellaneous/InterlockedIncrement/test2/paltest_interlockedincrement_test2 miscellaneous/InterlockedIncrement64/test1/paltest_interlockedincrement64_test1 miscellaneous/InterlockedIncrement64/test2/paltest_interlockedincrement64_test2 -miscellaneous/queryperformancecounter/test1/paltest_queryperformancecounter_test1 -miscellaneous/queryperformancefrequency/test1/paltest_queryperformancefrequency_test1 miscellaneous/SetEnvironmentVariableA/test1/paltest_setenvironmentvariablea_test1 miscellaneous/SetEnvironmentVariableA/test2/paltest_setenvironmentvariablea_test2 miscellaneous/SetEnvironmentVariableA/test3/paltest_setenvironmentvariablea_test3 diff --git a/src/coreclr/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp b/src/coreclr/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp index bfc1018f8db5fa..340a83e67d2104 100644 --- a/src/coreclr/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp +++ b/src/coreclr/pal/tests/palsuite/threading/NamedMutex/test1/namedmutex.cpp @@ -267,7 +267,7 @@ bool WaitForMutexToBeCreated(const char *testName, AutoCloseMutexHandle &m, cons { char eventName[MaxPathSize]; BuildName(testName, eventName, eventNamePrefix); - DWORD startTime = GetTickCount(); + DWORD startTime = (DWORD)minipal_lowres_ticks(); while (true) { m = TestOpenMutex(eventName); @@ -275,7 +275,7 @@ bool WaitForMutexToBeCreated(const char *testName, AutoCloseMutexHandle &m, cons { return true; } - if (GetTickCount() - startTime >= FailTimeoutMilliseconds) + if ((DWORD)minipal_lowres_ticks() - startTime >= FailTimeoutMilliseconds) { return false; } @@ -785,7 +785,7 @@ bool AbandonTests_Parent() // Since the child abandons the mutex, and a child process may not release the file lock on the shared memory file before // indicating completion to the parent, make sure to delete the shared memory file by repeatedly opening/closing the mutex // until the parent process becomes the last process to reference the mutex and closing it deletes the file. - DWORD startTime = GetTickCount(); + DWORD startTime = (DWORD)minipal_lowres_ticks(); while (true) { m.Close(); @@ -794,7 +794,7 @@ bool AbandonTests_Parent() break; } - TestAssert(GetTickCount() - startTime < FailTimeoutMilliseconds); + TestAssert((DWORD)minipal_lowres_ticks() - startTime < FailTimeoutMilliseconds); m = TestOpenMutex(BuildName(testName, name, NamePrefix)); } @@ -1182,7 +1182,7 @@ DWORD PALAPI StressTest(void *arg) { // Run the specified test continuously for the stress duration SIZE_T testIndex = reinterpret_cast(arg); - DWORD startTime = GetTickCount(); + DWORD startTime = (DWORD)minipal_lowres_ticks(); do { ++g_stressTestCounts[testIndex]; @@ -1193,7 +1193,7 @@ DWORD PALAPI StressTest(void *arg) } } while ( InterlockedCompareExchange(&g_stressResult, false, false) == true && - GetTickCount() - startTime < g_stressDurationMilliseconds); + (DWORD)minipal_lowres_ticks() - startTime < g_stressDurationMilliseconds); return 0; } diff --git a/src/coreclr/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/test1.cpp b/src/coreclr/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/test1.cpp index 2244d54e65e4b3..7f4f37e3e1c856 100644 --- a/src/coreclr/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/test1.cpp +++ b/src/coreclr/pal/tests/palsuite/threading/QueryThreadCycleTime/test1/test1.cpp @@ -56,7 +56,7 @@ PALTEST(threading_QueryThreadCycleTime_test1_paltest_querythreadcycletime_test1, LONG64 x; /* Init is in milliseconds, so we will convert later */ - Init = (LONG64)GetTickCount(); + Init = minipal_lowres_ticks(); x = Init + 3; volatile int counter; do { @@ -65,8 +65,8 @@ PALTEST(threading_QueryThreadCycleTime_test1_paltest_querythreadcycletime_test1, // spin to consume CPU time } - } while (x > GetTickCount()); - Expected += (GetTickCount() - Init) * MSEC_TO_NSEC; + } while (x > minipal_lowres_ticks()); + Expected += (minipal_lowres_ticks() - Init) * MSEC_TO_NSEC; /* Get a second count */ if (!QueryThreadCycleTime(cThread, (PULONG64)&SecondCount)) { diff --git a/src/coreclr/pal/tests/palsuite/threading/Sleep/test2/sleep.cpp b/src/coreclr/pal/tests/palsuite/threading/Sleep/test2/sleep.cpp index a4e1b465af2c68..6fb148b681f2fd 100644 --- a/src/coreclr/pal/tests/palsuite/threading/Sleep/test2/sleep.cpp +++ b/src/coreclr/pal/tests/palsuite/threading/Sleep/test2/sleep.cpp @@ -8,8 +8,6 @@ ** Purpose: Test to establish whether the Sleep function stops the thread from ** executing for the specified times. ** -** Dependencies: GetTickCount -** ** **=========================================================*/ diff --git a/src/coreclr/pal/tests/palsuite/wasm/index.html b/src/coreclr/pal/tests/palsuite/wasm/index.html index 9ca90c2d7c976e..28dd69524bb356 100644 --- a/src/coreclr/pal/tests/palsuite/wasm/index.html +++ b/src/coreclr/pal/tests/palsuite/wasm/index.html @@ -16,11 +16,9 @@

PAL Tests WASM

"file_io/SetFilePointer/test7/paltest_setfilepointer_test7", // tries to allocate 4GB of memory in MEMFS when run with chromedriver "filemapping_memmgt/MapViewOfFile/test1/paltest_mapviewoffile_test1", // infinite loop and then chrome crashes "filemapping_memmgt/ProbeMemory/ProbeMemory_neg1/paltest_probememory_probememory_neg1", - "miscellaneous/GetTickCount", // blocks main thread "miscellaneous/InterlockedCompareExchange/test2/paltest_interlockedcompareexchange_test2", // MT test "miscellaneous/InterlockedDecrement/test2/paltest_interlockeddecrement_test2", // MT test "miscellaneous/InterlockedIncrement/test2/paltest_interlockedincrement_test2", // MT test - "miscellaneous/queryperformancecounter", // blocks main thread "threading/", // we're single-threaded // "threading/CriticalSectionFunctions/test8/paltest_criticalsectionfunctions_test8", // blocks main thread ]; diff --git a/src/coreclr/tools/superpmi/superpmi-shared/simpletimer.cpp b/src/coreclr/tools/superpmi/superpmi-shared/simpletimer.cpp index 3a21e77029e126..87fe784e1c784c 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/simpletimer.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/simpletimer.cpp @@ -4,18 +4,14 @@ #include "standardpch.h" #include "logging.h" #include "simpletimer.h" +#include "minipal/time.h" SimpleTimer::SimpleTimer() { - start.QuadPart = 0; - stop.QuadPart = 0; - - BOOL retVal = ::QueryPerformanceFrequency(&proc_freq); - if (retVal == FALSE) - { - LogDebug("SimpleTimer::SimpleTimer unable to QPF. error was 0x%08x", ::GetLastError()); - DEBUG_BREAK; - } + start = 0; + stop = 0; + + proc_freq = minipal_hires_tick_frequency(); } SimpleTimer::~SimpleTimer() @@ -24,22 +20,12 @@ SimpleTimer::~SimpleTimer() void SimpleTimer::Start() { - BOOL retVal = ::QueryPerformanceCounter(&start); - if (retVal == FALSE) - { - LogDebug("SimpleTimer::Start unable to QPC. error was 0x%08x", ::GetLastError()); - DEBUG_BREAK; - } + start = minipal_hires_ticks(); } void SimpleTimer::Stop() { - BOOL retVal = ::QueryPerformanceCounter(&stop); - if (retVal == FALSE) - { - LogDebug("SimpleTimer::Stop unable to QPC. error was 0x%08x", ::GetLastError()); - DEBUG_BREAK; - } + stop = minipal_hires_ticks(); } double SimpleTimer::GetMilliseconds() @@ -49,5 +35,5 @@ double SimpleTimer::GetMilliseconds() double SimpleTimer::GetSeconds() { - return ((stop.QuadPart - start.QuadPart) / (double)proc_freq.QuadPart); + return ((stop - start) / (double)proc_freq); } diff --git a/src/coreclr/tools/superpmi/superpmi-shared/simpletimer.h b/src/coreclr/tools/superpmi/superpmi-shared/simpletimer.h index 69fb8760584647..48aae5e12b0fff 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/simpletimer.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/simpletimer.h @@ -4,6 +4,8 @@ #ifndef _SimpleTimer #define _SimpleTimer +#include + class SimpleTimer { public: @@ -16,8 +18,8 @@ class SimpleTimer double GetSeconds(); private: - LARGE_INTEGER proc_freq; - LARGE_INTEGER start; - LARGE_INTEGER stop; + int64_t proc_freq; + int64_t start; + int64_t stop; }; #endif diff --git a/src/coreclr/utilcode/cycletimer.cpp b/src/coreclr/utilcode/cycletimer.cpp index 946c72b278e287..10118bfa83b694 100644 --- a/src/coreclr/utilcode/cycletimer.cpp +++ b/src/coreclr/utilcode/cycletimer.cpp @@ -8,6 +8,7 @@ #include "winwrap.h" #include "assert.h" #include "utilcode.h" +#include "minipal/time.h" bool CycleTimer::GetThreadCyclesS(uint64_t* cycles) { @@ -26,25 +27,21 @@ double CycleTimer::CyclesPerSecond() // Windows *does* allow you to translate QueryPerformanceCounter counts into time, // however. So we'll assume that the clock speed stayed constant, and measure both the // QPC counts and cycles of a short loop, to get a conversion factor. - LARGE_INTEGER lpFrequency; - if (!QueryPerformanceFrequency(&lpFrequency)) return 0.0; - // Otherwise... - LARGE_INTEGER qpcStart; + int64_t lpFrequency = minipal_hires_tick_frequency(); + int64_t qpcStart = minipal_hires_ticks(); uint64_t cycleStart; - if (!QueryPerformanceCounter(&qpcStart)) return 0.0; if (!GetThreadCyclesS(&cycleStart)) return 0.0; volatile int sum = 0; for (int k = 0; k < SampleLoopSize; k++) { sum += k; } - LARGE_INTEGER qpcEnd; - if (!QueryPerformanceCounter(&qpcEnd)) return 0.0; + int64_t qpcEnd = minipal_hires_ticks(); uint64_t cycleEnd; if (!GetThreadCyclesS(&cycleEnd)) return 0.0; - double qpcTicks = ((double)qpcEnd.QuadPart) - ((double)qpcStart.QuadPart); - double secs = (qpcTicks / ((double)lpFrequency.QuadPart)); + double qpcTicks = ((double)qpcEnd) - ((double)qpcStart); + double secs = (qpcTicks / ((double)lpFrequency)); double cycles = ((double)cycleEnd) - ((double)cycleStart); return cycles / secs; } diff --git a/src/coreclr/utilcode/stresslog.cpp b/src/coreclr/utilcode/stresslog.cpp index 8908f30a9e9110..e837e86712d789 100644 --- a/src/coreclr/utilcode/stresslog.cpp +++ b/src/coreclr/utilcode/stresslog.cpp @@ -15,6 +15,7 @@ #include "ex.h" #define DONOT_DEFINE_ETW_CALLBACK #include "eventtracebase.h" +#include "minipal/time.h" #if !defined(STRESS_LOG_READONLY) #ifdef HOST_WINDOWS @@ -58,15 +59,11 @@ uint64_t getTimeStamp() { } #else // HOST_X86 -uint64_t getTimeStamp() { +uint64_t getTimeStamp() +{ STATIC_CONTRACT_LEAF; - LARGE_INTEGER ret; - ZeroMemory(&ret, sizeof(LARGE_INTEGER)); - - QueryPerformanceCounter(&ret); - - return ret.QuadPart; + return (uint64_t)minipal_hires_ticks(); } #endif // HOST_X86 @@ -127,10 +124,7 @@ uint64_t getTickFrequency() */ uint64_t getTickFrequency() { - LARGE_INTEGER ret; - ZeroMemory(&ret, sizeof(LARGE_INTEGER)); - QueryPerformanceFrequency(&ret); - return ret.QuadPart; + return (uint64_t)minipal_hires_tick_frequency(); } #endif // HOST_X86 diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index 53f192d8bc976f..d283b276ae5cea 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -163,6 +163,7 @@ #include "pgo.h" #include "pendingload.h" #include "cdacplatformmetadata.hpp" +#include "minipal/time.h" #ifndef TARGET_UNIX #include "dwreport.h" @@ -484,10 +485,10 @@ void InitGSCookie() void * pf = &__security_check_cookie; pf = NULL; - GSCookie val = (GSCookie)(__security_cookie ^ GetTickCount()); + GSCookie val = (GSCookie)(__security_cookie ^ minipal_lowres_ticks()); #else // !TARGET_UNIX // REVIEW: Need something better for PAL... - GSCookie val = (GSCookie)GetTickCount(); + GSCookie val = (GSCookie)minipal_lowres_ticks(); #endif // !TARGET_UNIX #ifdef _DEBUG diff --git a/src/coreclr/vm/codepitchingmanager.cpp b/src/coreclr/vm/codepitchingmanager.cpp index f3ca5cae92282b..7cedeb0d2210cb 100644 --- a/src/coreclr/vm/codepitchingmanager.cpp +++ b/src/coreclr/vm/codepitchingmanager.cpp @@ -37,6 +37,7 @@ #if defined(FEATURE_JIT_PITCHING) #include "threadsuspend.h" +#include "minipal/time.h" static PtrHashMap* s_pPitchingCandidateMethods = nullptr; static PtrHashMap* s_pPitchingCandidateSizes = nullptr; @@ -427,7 +428,7 @@ EXTERN_C void CheckStacksAndPitch() if ((CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchEnabled) != 0) && (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchMemThreshold) != 0) && (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchTimeInterval) == 0 || - ((::GetTickCount64() - s_JitPitchLastTick) > CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchTimeInterval)))) + ((minipal_lowres_ticks() - s_JitPitchLastTick) > CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchTimeInterval)))) { SimpleReadLockHolder srlh(s_totalNCSizeLock); @@ -467,7 +468,7 @@ EXTERN_C void CheckStacksAndPitch() s_pPitchingCandidateSizes->Compact(); } - s_JitPitchLastTick = ::GetTickCount64(); + s_JitPitchLastTick = minipal_lowres_ticks(); ThreadSuspend::RestartEE(FALSE, TRUE); } diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h index fab56cdf642685..4e99da6129b95d 100644 --- a/src/coreclr/vm/ecalllist.h +++ b/src/coreclr/vm/ecalllist.h @@ -69,8 +69,6 @@ FCFuncEnd() FCFuncStart(gEnvironmentFuncs) FCFuncElement("get_CurrentManagedThreadId", JIT_GetCurrentManagedThreadId) - FCFuncElement("get_TickCount", SystemNative::GetTickCount) - FCFuncElement("get_TickCount64", SystemNative::GetTickCount64) FCFuncElement("set_ExitCode", SystemNative::SetExitCode) FCFuncElement("get_ExitCode", SystemNative::GetExitCode) FCFuncEnd() diff --git a/src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h b/src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h index da68b1551cee3f..49708badca33d0 100644 --- a/src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h +++ b/src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h @@ -19,6 +19,7 @@ #include "hostinformation.h" #include #include +#include #undef EP_INFINITE_WAIT #define EP_INFINITE_WAIT INFINITE @@ -990,11 +991,7 @@ ep_rt_perf_counter_query (void) { STATIC_CONTRACT_NOTHROW; - LARGE_INTEGER value; - if (QueryPerformanceCounter (&value)) - return static_cast(value.QuadPart); - else - return 0; + return minipal_hires_ticks(); } static @@ -1004,11 +1001,7 @@ ep_rt_perf_frequency_query (void) { STATIC_CONTRACT_NOTHROW; - LARGE_INTEGER value; - if (QueryPerformanceFrequency (&value)) - return static_cast(value.QuadPart); - else - return 0; + return minipal_hires_tick_frequency(); } static diff --git a/src/coreclr/vm/eventpipeinternal.cpp b/src/coreclr/vm/eventpipeinternal.cpp index 1fabe8f08ef967..e981e629055530 100644 --- a/src/coreclr/vm/eventpipeinternal.cpp +++ b/src/coreclr/vm/eventpipeinternal.cpp @@ -10,6 +10,7 @@ #endif // TARGET_UNIX #include +#include #ifdef FEATURE_PERFTRACING @@ -79,7 +80,7 @@ extern "C" BOOL QCALLTYPE EventPipeInternal_GetSessionInfo(UINT64 sessionID, Eve { pSessionInfo->StartTimeAsUTCFileTime = EventPipeAdapter::GetSessionStartTime(pSession); pSessionInfo->StartTimeStamp.QuadPart = EventPipeAdapter::GetSessionStartTimestamp(pSession); - QueryPerformanceFrequency(&pSessionInfo->TimeStampFrequency); + pSessionInfo->TimeStampFrequency.QuadPart = minipal_hires_tick_frequency(); retVal = true; } } diff --git a/src/coreclr/vm/eventtrace.cpp b/src/coreclr/vm/eventtrace.cpp index 651d8b0e4e9d20..238ba6a69514c1 100644 --- a/src/coreclr/vm/eventtrace.cpp +++ b/src/coreclr/vm/eventtrace.cpp @@ -1012,7 +1012,7 @@ void ETW::TypeSystemLog::SendObjectAllocatedEvent(Object * pObject) } SIZE_T nTotalSizeForTypeSample = size; - DWORD dwTickNow = GetTickCount(); + DWORD dwTickNow = (DWORD)minipal_lowres_ticks(); DWORD dwObjectCountForTypeSample = 0; // Get stats for type diff --git a/src/coreclr/vm/finalizerthread.cpp b/src/coreclr/vm/finalizerthread.cpp index 21bd8e58416ba8..464f2baecf7c2a 100644 --- a/src/coreclr/vm/finalizerthread.cpp +++ b/src/coreclr/vm/finalizerthread.cpp @@ -17,10 +17,11 @@ BOOL FinalizerThread::fQuitFinalizer = FALSE; #if defined(__linux__) && defined(FEATURE_EVENT_TRACE) +#include "minipal/time.h" #define LINUX_HEAP_DUMP_TIME_OUT 10000 extern bool s_forcedGCInProgress; -ULONGLONG FinalizerThread::LastHeapDumpTime = 0; +int64_t FinalizerThread::LastHeapDumpTime = 0; Volatile g_TriggerHeapDump = FALSE; #endif // __linux__ @@ -271,7 +272,7 @@ VOID FinalizerThread::FinalizerThreadWorker(void *args) } #if defined(__linux__) && defined(FEATURE_EVENT_TRACE) - if (g_TriggerHeapDump && (CLRGetTickCount64() > (LastHeapDumpTime + LINUX_HEAP_DUMP_TIME_OUT))) + if (g_TriggerHeapDump && (minipal_lowres_ticks() > (LastHeapDumpTime + LINUX_HEAP_DUMP_TIME_OUT))) { s_forcedGCInProgress = true; GetFinalizerThread()->DisablePreemptiveGC(); @@ -279,7 +280,7 @@ VOID FinalizerThread::FinalizerThreadWorker(void *args) GetFinalizerThread()->EnablePreemptiveGC(); s_forcedGCInProgress = false; - LastHeapDumpTime = CLRGetTickCount64(); + LastHeapDumpTime = minipal_lowres_ticks(); g_TriggerHeapDump = FALSE; } #endif diff --git a/src/coreclr/vm/finalizerthread.h b/src/coreclr/vm/finalizerthread.h index eda53d2e2d7a69..46d104853f380c 100644 --- a/src/coreclr/vm/finalizerthread.h +++ b/src/coreclr/vm/finalizerthread.h @@ -10,7 +10,7 @@ class FinalizerThread static BOOL fQuitFinalizer; #if defined(__linux__) && defined(FEATURE_EVENT_TRACE) - static ULONGLONG LastHeapDumpTime; + static int64_t LastHeapDumpTime; #endif static CLREvent *hEventFinalizer; diff --git a/src/coreclr/vm/hash.cpp b/src/coreclr/vm/hash.cpp index 80bf159f9c31b6..e06370d5bc466a 100644 --- a/src/coreclr/vm/hash.cpp +++ b/src/coreclr/vm/hash.cpp @@ -19,6 +19,7 @@ Module Name: #include "syncclean.hpp" #include "threadsuspend.h" +#include "minipal/time.h" //--------------------------------------------------------------------- // Array of primes, used by hash table to choose the number of buckets @@ -1184,7 +1185,7 @@ void HashMap::HashMapTest() LookupPerfTest(table, MinThreshold); - INT64 t0 = GetTickCount(); + INT64 t0 = minipal_lowres_ticks(); INT64 t1; for(int rep = 0; rep < 10000000; rep++) { for(unsigned int i=MinThreshold; i < MaxThreshold; i++) { @@ -1199,7 +1200,7 @@ void HashMap::HashMapTest() table->InsertValue(i, i); if (rep % 500 == 0) { - t1 = GetTickCount(); + t1 = minipal_lowres_ticks(); minipal_log_print_info("Repetition %d, took %d ms\n", rep, (int) (t1-t0)); t0 = t1; LookupPerfTest(table, MinThreshold); @@ -1212,7 +1213,7 @@ void HashMap::HashMapTest() // For testing purposes only. void HashMap::LookupPerfTest(HashMap * table, const unsigned int MinThreshold) { - INT64 t0 = GetTickCount(); + INT64 t0 = minipal_lowres_ticks(); for(int rep = 0; rep < 1000; rep++) { for(unsigned int i=2; iLookupValue(i, i); @@ -1222,7 +1223,7 @@ void HashMap::LookupPerfTest(HashMap * table, const unsigned int MinThreshold) } } } - INT64 t1 = GetTickCount(); + INT64 t1 = minipal_lowres_ticks(); for(unsigned int i = MinThreshold * 80; i < MinThreshold * 80 + 1000; i++) table->LookupValue(i, i); //cout << "Lookup perf test (1000 * " << MinThreshold << ": " << (t1-t0) << " ms." << endl; diff --git a/src/coreclr/vm/jithost.cpp b/src/coreclr/vm/jithost.cpp index 03f97bf7d477a5..44b10f66c103e5 100644 --- a/src/coreclr/vm/jithost.cpp +++ b/src/coreclr/vm/jithost.cpp @@ -6,6 +6,7 @@ #include "utilcode.h" #include "corjit.h" #include "jithost.h" +#include "minipal/time.h" void* JitHost::allocateMemory(size_t size) { @@ -176,7 +177,7 @@ void JitHost::reclaim() { if (m_pCurrentCachedList != NULL || m_pPreviousCachedList != NULL) { - DWORD ticks = ::GetTickCount(); + DWORD ticks = (DWORD)minipal_lowres_ticks(); if (m_lastFlush == 0) // Just update m_lastFlush first time around { diff --git a/src/coreclr/vm/multicorejit.cpp b/src/coreclr/vm/multicorejit.cpp index 98baf1206f1de4..10560356cb538f 100644 --- a/src/coreclr/vm/multicorejit.cpp +++ b/src/coreclr/vm/multicorejit.cpp @@ -20,6 +20,7 @@ #include "array.h" #include "fstream.h" #include "hash.h" +#include "minipal/time.h" #include "appdomain.hpp" #include "qcall.h" @@ -99,7 +100,7 @@ void _MulticoreJitTrace(const char * format, ...) if (s_startTick == 0) { - s_startTick = GetTickCount(); + s_startTick = (unsigned)minipal_lowres_ticks(); } va_list args; @@ -108,7 +109,7 @@ void _MulticoreJitTrace(const char * format, ...) #ifdef LOGGING LogSpew2 (LF2_MULTICOREJIT, LL_INFO100, "Mcj "); LogSpew2Valist(LF2_MULTICOREJIT, LL_INFO100, format, args); - LogSpew2 (LF2_MULTICOREJIT, LL_INFO100, ", (time=%d ms)\n", GetTickCount() - s_startTick); + LogSpew2 (LF2_MULTICOREJIT, LL_INFO100, ", (time=%d ms)\n", (unsigned)minipal_lowres_ticks() - s_startTick); #else // Following LogSpewValist(DWORD facility, DWORD level, const char *fmt, va_list args) @@ -118,7 +119,7 @@ void _MulticoreJitTrace(const char * format, ...) len = sprintf_s(buffer, ARRAY_SIZE(buffer), "Mcj TID %04x: ", GetCurrentThreadId()); len += _vsnprintf_s(buffer + len, ARRAY_SIZE(buffer) - len, format, args); - len += sprintf_s(buffer + len, ARRAY_SIZE(buffer) - len, ", (time=%d ms)\r\n", GetTickCount() - s_startTick); + len += sprintf_s(buffer + len, ARRAY_SIZE(buffer) - len, ", (time=%d ms)\r\n", (unsigned)minipal_lowres_ticks() - s_startTick); OutputDebugStringA(buffer); #endif diff --git a/src/coreclr/vm/multicorejitplayer.cpp b/src/coreclr/vm/multicorejitplayer.cpp index fcc4a46a33fcf1..a3b54d28d802b3 100644 --- a/src/coreclr/vm/multicorejitplayer.cpp +++ b/src/coreclr/vm/multicorejitplayer.cpp @@ -21,6 +21,7 @@ #include "fstream.h" #include "hash.h" #include "clrex.h" +#include "minipal/time.h" #include "appdomain.hpp" @@ -382,7 +383,7 @@ MulticoreJitProfilePlayer::MulticoreJitProfilePlayer(AssemblyBinder * pBinder, L m_pFileBuffer = NULL; m_nFileSize = 0; - m_nStartTime = GetTickCount(); + m_nStartTime = (unsigned int)minipal_lowres_ticks(); } @@ -733,7 +734,7 @@ bool MulticoreJitProfilePlayer::ShouldAbort(bool fast) const return false; } - if (GetTickCount() - m_nStartTime > MULTICOREJITLIFE) + if ((unsigned int)minipal_lowres_ticks() - m_nStartTime > MULTICOREJITLIFE) { MulticoreJitTrace(("MulticoreJitProfilePlayer::ShouldAbort time over")); @@ -1117,7 +1118,7 @@ HRESULT MulticoreJitProfilePlayer::PlayProfile() HRESULT hr = S_OK; - DWORD start = GetTickCount(); + DWORD start = (DWORD)minipal_lowres_ticks(); Thread * pThread = GetThread(); @@ -1311,7 +1312,7 @@ HRESULT MulticoreJitProfilePlayer::PlayProfile() } } - start = GetTickCount() - start; + start = (DWORD)minipal_lowres_ticks() - start; { FireEtwThreadTerminated((ULONGLONG) pThread, (ULONGLONG) GetAppDomain(), GetClrInstanceId()); diff --git a/src/coreclr/vm/profdetach.cpp b/src/coreclr/vm/profdetach.cpp index 28b8442454cf0c..c487074500fcc9 100644 --- a/src/coreclr/vm/profdetach.cpp +++ b/src/coreclr/vm/profdetach.cpp @@ -17,6 +17,7 @@ #include "profilinghelper.h" #include "profilinghelper.inl" #include "eetoprofinterfaceimpl.inl" +#include "minipal/time.h" // Class static member variables CQuickArrayList ProfilingAPIDetach::s_profilerDetachInfos; @@ -224,7 +225,7 @@ HRESULT ProfilingAPIDetach::RequestProfilerDetach(ProfilerInfo *pProfilerInfo, D { ProfilerDetachInfo detachInfo; detachInfo.m_pProfilerInfo = pProfilerInfo; - detachInfo.m_ui64DetachStartTime = CLRGetTickCount64(); + detachInfo.m_ui64DetachStartTime = minipal_lowres_ticks(); detachInfo.m_dwExpectedCompletionMilliseconds = dwExpectedCompletionMilliseconds; s_profilerDetachInfos.Push(detachInfo); } @@ -422,7 +423,7 @@ void ProfilingAPIDetach::SleepWhileProfilerEvacuates(ProfilerDetachInfo *pDetach // (but not too soon) // * Occasionally thereafter (steady state) - ULONGLONG ui64ElapsedMilliseconds = CLRGetTickCount64() - ui64DetachStartTime; + ULONGLONG ui64ElapsedMilliseconds = minipal_lowres_ticks() - ui64DetachStartTime; ULONGLONG ui64SleepMilliseconds; if (ui64ExpectedCompletionMilliseconds > ui64ElapsedMilliseconds) { diff --git a/src/coreclr/vm/syncblk.cpp b/src/coreclr/vm/syncblk.cpp index 0d4e05a3bd4382..99b52cf42232c0 100644 --- a/src/coreclr/vm/syncblk.cpp +++ b/src/coreclr/vm/syncblk.cpp @@ -28,6 +28,7 @@ #include "corhost.h" #include "comdelegate.h" #include "finalizerthread.h" +#include "minipal/time.h" #ifdef FEATURE_COMINTEROP #include "runtimecallablewrapper.h" @@ -2477,15 +2478,15 @@ inline void LogContention() #define LogContention() #endif -double ComputeElapsedTimeInNanosecond(LARGE_INTEGER startTicks, LARGE_INTEGER endTicks) +double ComputeElapsedTimeInNanosecond(int64_t startTicks, int64_t endTicks) { - static LARGE_INTEGER freq; - if (freq.QuadPart == 0) - QueryPerformanceFrequency(&freq); + static int64_t freq; + if (freq == 0) + freq = minipal_hires_tick_frequency(); const double NsPerSecond = 1000 * 1000 * 1000; - LONGLONG elapsedTicks = endTicks.QuadPart - startTicks.QuadPart; - return (elapsedTicks * NsPerSecond) / freq.QuadPart; + LONGLONG elapsedTicks = endTicks - startTicks; + return (elapsedTicks * NsPerSecond) / freq; } BOOL AwareLock::EnterEpilogHelper(Thread* pCurThread, INT32 timeOut) @@ -2510,12 +2511,12 @@ BOOL AwareLock::EnterEpilogHelper(Thread* pCurThread, INT32 timeOut) OBJECTREF obj = GetOwningObject(); - LARGE_INTEGER startTicks = { {0} }; + int64_t startTicks = 0; bool isContentionKeywordEnabled = ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context, TRACE_LEVEL_INFORMATION, CLR_CONTENTION_KEYWORD); if (isContentionKeywordEnabled) { - QueryPerformanceCounter(&startTicks); + startTicks = minipal_hires_ticks(); if (InterlockedCompareExchangeT(&m_emittedLockCreatedEvent, 1, 0) == 0) { @@ -2550,7 +2551,7 @@ BOOL AwareLock::EnterEpilogHelper(Thread* pCurThread, INT32 timeOut) // Measure the time we wait so that, in the case where we wake up // and fail to acquire the mutex, we can adjust remaining timeout // accordingly. - ULONGLONG start = CLRGetTickCount64(); + int64_t start = minipal_lowres_ticks(); // It is likely the case that An APC threw an exception, for instance Thread.Interrupt(). The wait subsystem // guarantees that if a signal to the event being waited upon is observed by the woken thread, that thread's @@ -2638,8 +2639,8 @@ BOOL AwareLock::EnterEpilogHelper(Thread* pCurThread, INT32 timeOut) // case is taken care of by 32-bit modulo arithmetic automatically. if (timeOut != (INT32)INFINITE) { - ULONGLONG end = CLRGetTickCount64(); - ULONGLONG duration; + int64_t end = minipal_lowres_ticks(); + int64_t duration; if (end == start) { duration = 1; @@ -2648,7 +2649,7 @@ BOOL AwareLock::EnterEpilogHelper(Thread* pCurThread, INT32 timeOut) { duration = end - start; } - duration = min(duration, (ULONGLONG)timeOut); + duration = min(duration, (int64_t)timeOut); timeOut -= (INT32)duration; } } @@ -2660,8 +2661,7 @@ BOOL AwareLock::EnterEpilogHelper(Thread* pCurThread, INT32 timeOut) if (isContentionKeywordEnabled) { - LARGE_INTEGER endTicks; - QueryPerformanceCounter(&endTicks); + int64_t endTicks = minipal_hires_ticks(); double elapsedTimeInNanosecond = ComputeElapsedTimeInNanosecond(startTicks, endTicks); diff --git a/src/coreclr/vm/syncblk.inl b/src/coreclr/vm/syncblk.inl index be935d084840b5..a9ea995d721297 100644 --- a/src/coreclr/vm/syncblk.inl +++ b/src/coreclr/vm/syncblk.inl @@ -438,7 +438,7 @@ FORCEINLINE void AwareLock::RecordWaiterStarvationStartTime() { WRAPPER_NO_CONTRACT; - DWORD currentTimeMs = GetTickCount(); + DWORD currentTimeMs = (DWORD)minipal_lowres_ticks(); if (currentTimeMs == 0) { // Don't record zero, that value is reserved for identifying that a time is not recorded @@ -455,7 +455,7 @@ FORCEINLINE bool AwareLock::ShouldStopPreemptingWaiters() const DWORD waiterStarvationStartTimeMs = m_waiterStarvationStartTimeMs; return waiterStarvationStartTimeMs != 0 && - GetTickCount() - waiterStarvationStartTimeMs >= WaiterStarvationDurationMsBeforeStoppingPreemptingWaiters; + (DWORD)minipal_lowres_ticks() - waiterStarvationStartTimeMs >= WaiterStarvationDurationMsBeforeStoppingPreemptingWaiters; } FORCEINLINE void AwareLock::SpinWait(const YieldProcessorNormalizationInfo &normalizationInfo, DWORD spinIteration) diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp index 1685042586057f..b3ad5b35b47960 100644 --- a/src/coreclr/vm/threads.cpp +++ b/src/coreclr/vm/threads.cpp @@ -31,6 +31,7 @@ #include "appdomain.inl" #include "vmholder.h" #include "exceptmacros.h" +#include "minipal/time.h" #ifdef FEATURE_COMINTEROP #include "runtimecallablewrapper.h" @@ -3329,7 +3330,7 @@ DWORD Thread::DoAppropriateWaitWorker(int countHandles, HANDLE *handles, BOOL wa retry: if (millis != INFINITE) { - dwStart = CLRGetTickCount64(); + dwStart = minipal_lowres_ticks(); } if (tryNonblockingWaitFirst) @@ -3355,7 +3356,7 @@ DWORD Thread::DoAppropriateWaitWorker(int countHandles, HANDLE *handles, BOOL wa // in the thread state bits. Otherwise we just go back to sleep again. if (millis != INFINITE) { - dwEnd = CLRGetTickCount64(); + dwEnd = minipal_lowres_ticks(); if (dwEnd - dwStart >= millis) { ret = WAIT_TIMEOUT; @@ -3438,7 +3439,7 @@ DWORD Thread::DoAppropriateWaitWorker(int countHandles, HANDLE *handles, BOOL wa // Compute the new timeout value by assume that the timeout // is not large enough for more than one wrap - dwEnd = CLRGetTickCount64(); + dwEnd = minipal_lowres_ticks(); if (millis != INFINITE) { if (dwEnd - dwStart >= millis) @@ -3566,7 +3567,7 @@ DWORD Thread::DoSignalAndWaitWorker(HANDLE* pHandles, DWORD millis,BOOL alertabl if (INFINITE != millis) { - dwStart = CLRGetTickCount64(); + dwStart = minipal_lowres_ticks(); } ret = SignalObjectAndWait(pHandles[0], pHandles[1], millis, alertable); @@ -3585,7 +3586,7 @@ DWORD Thread::DoSignalAndWaitWorker(HANDLE* pHandles, DWORD millis,BOOL alertabl } if (INFINITE != millis) { - dwEnd = CLRGetTickCount64(); + dwEnd = minipal_lowres_ticks(); if (dwStart + millis <= dwEnd) { ret = WAIT_TIMEOUT; @@ -3595,7 +3596,7 @@ DWORD Thread::DoSignalAndWaitWorker(HANDLE* pHandles, DWORD millis,BOOL alertabl { millis -= (DWORD)(dwEnd - dwStart); } - dwStart = CLRGetTickCount64(); + dwStart = minipal_lowres_ticks(); } //Retry case we don't want to signal again so only do the wait... ret = WaitForSingleObjectEx(pHandles[1],millis,TRUE); @@ -3957,7 +3958,7 @@ void Thread::UserSleep(INT32 time) DWORD dwTime = (DWORD)time; retry: - ULONGLONG start = CLRGetTickCount64(); + ULONGLONG start = minipal_lowres_ticks(); res = ClrSleepEx (dwTime, TRUE); @@ -3977,7 +3978,7 @@ void Thread::UserSleep(INT32 time) } else { - ULONGLONG actDuration = CLRGetTickCount64() - start; + ULONGLONG actDuration = minipal_lowres_ticks() - start; if (dwTime > actDuration) { diff --git a/src/coreclr/vm/threadsuspend.cpp b/src/coreclr/vm/threadsuspend.cpp index 4e7a0020927076..e3c8f4f7546813 100644 --- a/src/coreclr/vm/threadsuspend.cpp +++ b/src/coreclr/vm/threadsuspend.cpp @@ -209,7 +209,7 @@ Thread::SuspendThreadResult Thread::SuspendThread(BOOL fOneTryOnly, DWORD *pdwSu #if defined(_DEBUG) int nCnt = 0; bool bDiagSuspend = g_pConfig->GetDiagnosticSuspend(); - ULONGLONG i64TimestampStart = CLRGetTickCount64(); + ULONGLONG i64TimestampStart = minipal_lowres_ticks(); ULONGLONG i64TimestampCur = i64TimestampStart; ULONGLONG i64TimestampPrev = i64TimestampStart; @@ -321,7 +321,7 @@ Thread::SuspendThreadResult Thread::SuspendThread(BOOL fOneTryOnly, DWORD *pdwSu if ((!fOneTryOnly) && bDiagSuspend) { while ( m_dwForbidSuspendThread != 0 && - CLRGetTickCount64()-i64TimestampStart < nCnt*(i64TimestampTicksMax>>3) ) + minipal_lowres_ticks()-i64TimestampStart < nCnt*(i64TimestampTicksMax>>3) ) { if (g_SystemInfo.dwNumberOfProcessors > 1) { @@ -379,9 +379,9 @@ Thread::SuspendThreadResult Thread::SuspendThread(BOOL fOneTryOnly, DWORD *pdwSu #if defined(_DEBUG) i64TimestampPrev = i64TimestampCur; - i64TimestampCur = CLRGetTickCount64(); - // CLRGetTickCount64() is global per machine (not per CPU, like getTimeStamp()). - // Next ASSERT states that CLRGetTickCount64() is increasing, or has wrapped. + i64TimestampCur = minipal_lowres_ticks(); + // minipal_lowres_ticks() is global per machine (not per CPU, like getTimeStamp()). + // Next ASSERT states that minipal_lowres_ticks() is increasing, or has wrapped. // If it wrapped, the last iteration should have executed faster then 0.5 seconds. _ASSERTE(i64TimestampCur >= i64TimestampPrev || i64TimestampCur <= 500); @@ -1202,8 +1202,8 @@ Thread::UserAbort(EEPolicy::ThreadAbortTypes abortType, DWORD timeout) // Swap in timeout if (timeout != INFINITE) { - ULONG64 curTime = CLRGetTickCount64(); - ULONG64 newEndTime = curTime + timeout; + ULONGLONG curTime = minipal_lowres_ticks(); + ULONGLONG newEndTime = curTime + timeout; SetAbortEndTime(newEndTime, abortType == EEPolicy::TA_Rude); } @@ -1263,7 +1263,7 @@ Thread::UserAbort(EEPolicy::ThreadAbortTypes abortType, DWORD timeout) ULONGLONG abortEndTime = GetAbortEndTime(); if (abortEndTime != MAXULONGLONG) { - ULONGLONG now_time = CLRGetTickCount64(); + ULONGLONG now_time = minipal_lowres_ticks(); if (now_time >= abortEndTime) { @@ -1657,7 +1657,7 @@ Thread::UserAbort(EEPolicy::ThreadAbortTypes abortType, DWORD timeout) return S_OK; } - ULONGLONG curTime = CLRGetTickCount64(); + ULONGLONG curTime = minipal_lowres_ticks(); if (curTime >= GetAbortEndTime()) { break; @@ -6056,20 +6056,13 @@ DWORD StatisticsBase::secondsToDisplay = 0; DWORD StatisticsBase::GetTime() { LIMITED_METHOD_CONTRACT; - LARGE_INTEGER large; if (divisor == 0) { - if (QueryPerformanceFrequency(&large) && (large.QuadPart != 0)) - divisor = (DWORD)(large.QuadPart / (1000 * 1000)); // microseconds - else - divisor = 1; + divisor = (DWORD)minipal_hires_tick_frequency() / (1000 * 1000); // microseconds } - if (QueryPerformanceCounter(&large)) - return (DWORD) (large.QuadPart / divisor); - else - return 0; + return (DWORD) (minipal_hires_ticks() / divisor); } DWORD StatisticsBase::GetElapsed(DWORD start, DWORD stop) @@ -6100,7 +6093,7 @@ void StatisticsBase::RollOverIfNeeded() const DWORD RolloverInterval = 3900; // every so often, print a summary of our statistics - DWORD ticksNow = GetTickCount(); + DWORD ticksNow = (DWORD)minipal_lowres_ticks(); if (secondsToDisplay == 0) { @@ -6115,7 +6108,7 @@ void StatisticsBase::RollOverIfNeeded() { DisplayAndUpdate(); - startTick = GetTickCount(); + startTick = (DWORD)minipal_lowres_ticks(); // Our counters are 32 bits and can count to 4 GB in microseconds or 4K in seconds. // Reset when we get close to overflowing diff --git a/src/coreclr/vm/tieredcompilation.cpp b/src/coreclr/vm/tieredcompilation.cpp index 2d1a8bddfdd919..1dd18ca48a0bab 100644 --- a/src/coreclr/vm/tieredcompilation.cpp +++ b/src/coreclr/vm/tieredcompilation.cpp @@ -12,6 +12,7 @@ #include "log.h" #include "threadsuspend.h" #include "tieredcompilation.h" +#include "minipal/time.h" // TieredCompilationManager determines which methods should be recompiled and // how they should be recompiled to best optimize the running code. It then @@ -500,12 +501,10 @@ void TieredCompilationManager::BackgroundWorkerStart() int processorCount = GetCurrentProcessCpuCount(); _ASSERTE(processorCount > 0); - LARGE_INTEGER li; - QueryPerformanceFrequency(&li); - UINT64 ticksPerS = li.QuadPart; - UINT64 maxWorkDurationTicks = ticksPerS * 50 / 1000; // 50 ms - UINT64 minWorkDurationTicks = min(ticksPerS * processorCount / 1000, maxWorkDurationTicks); // ms (capped) - UINT64 workDurationTicks = minWorkDurationTicks; + int64_t ticksPerS = minipal_hires_tick_frequency(); + int64_t maxWorkDurationTicks = ticksPerS * 50 / 1000; // 50 ms + int64_t minWorkDurationTicks = min(ticksPerS * processorCount / 1000, maxWorkDurationTicks); // ms (capped) + int64_t workDurationTicks = minWorkDurationTicks; while (true) { @@ -713,9 +712,9 @@ void TieredCompilationManager::AsyncCompleteCallCounting() // optimizations enabled and then installed as the active implementation // of the method entrypoint. bool TieredCompilationManager::DoBackgroundWork( - UINT64 *workDurationTicksRef, - UINT64 minWorkDurationTicks, - UINT64 maxWorkDurationTicks) + int64_t *workDurationTicksRef, + int64_t minWorkDurationTicks, + int64_t maxWorkDurationTicks) { WRAPPER_NO_CONTRACT; _ASSERTE(GetThread() == s_backgroundWorkerThread); @@ -723,7 +722,7 @@ bool TieredCompilationManager::DoBackgroundWork( _ASSERTE(workDurationTicksRef != nullptr); _ASSERTE(minWorkDurationTicks <= maxWorkDurationTicks); - UINT64 workDurationTicks = *workDurationTicksRef; + int64_t workDurationTicks = *workDurationTicksRef; _ASSERTE(workDurationTicks >= minWorkDurationTicks); _ASSERTE(workDurationTicks <= maxWorkDurationTicks); @@ -740,10 +739,8 @@ bool TieredCompilationManager::DoBackgroundWork( bool sendStopEvent = true; bool allMethodsJitted = false; UINT32 jittedMethodCount = 0; - LARGE_INTEGER li; - QueryPerformanceCounter(&li); - UINT64 startTicks = li.QuadPart; - UINT64 previousTicks = startTicks; + int64_t startTicks = minipal_hires_ticks(); + int64_t previousTicks = startTicks; do { @@ -822,8 +819,7 @@ bool TieredCompilationManager::DoBackgroundWork( // Yield the thread periodically to give preference to possibly more important work - QueryPerformanceCounter(&li); - UINT64 currentTicks = li.QuadPart; + int64_t currentTicks = minipal_hires_ticks(); if (currentTicks - startTicks < workDurationTicks) { previousTicks = currentTicks; @@ -849,11 +845,10 @@ bool TieredCompilationManager::DoBackgroundWork( ETW::CompilationLog::TieredCompilation::Runtime::SendBackgroundJitStop(countOfMethodsToOptimize, jittedMethodCount); } - UINT64 beforeSleepTicks = currentTicks; + int64_t beforeSleepTicks = currentTicks; ClrSleepEx(0, false); - QueryPerformanceCounter(&li); - currentTicks = li.QuadPart; + currentTicks = minipal_hires_ticks(); // Depending on how oversubscribed thread usage is on the system, the sleep may have caused this thread to not be // scheduled for a long time. Yielding the thread too frequently may significantly slow down the background work, which @@ -864,8 +859,8 @@ bool TieredCompilationManager::DoBackgroundWork( // work duration is capped to a maximum and since a long sleep delay is likely to repeat, to avoid going back to // too-frequent yielding too quickly, the background work duration is decayed back to the minimum if the sleep duration // becomes consistently short. - UINT64 newWorkDurationTicks = (currentTicks - beforeSleepTicks) / 4; - UINT64 decayedWorkDurationTicks = (workDurationTicks + workDurationTicks / 2) / 2; + int64_t newWorkDurationTicks = (currentTicks - beforeSleepTicks) / 4; + int64_t decayedWorkDurationTicks = (workDurationTicks + workDurationTicks / 2) / 2; workDurationTicks = newWorkDurationTicks < decayedWorkDurationTicks ? decayedWorkDurationTicks : newWorkDurationTicks; if (workDurationTicks < minWorkDurationTicks) { diff --git a/src/coreclr/vm/tieredcompilation.h b/src/coreclr/vm/tieredcompilation.h index 7177c6cc32a41e..b39ef788a72e12 100644 --- a/src/coreclr/vm/tieredcompilation.h +++ b/src/coreclr/vm/tieredcompilation.h @@ -71,7 +71,7 @@ class TieredCompilationManager private: static DWORD StaticBackgroundWorkCallback(void* args); - bool DoBackgroundWork(UINT64 *workDurationTicksRef, UINT64 minWorkDurationTicks, UINT64 maxWorkDurationTicks); + bool DoBackgroundWork(int64_t *workDurationTicksRef, int64_t minWorkDurationTicks, int64_t maxWorkDurationTicks); private: void OptimizeMethod(NativeCodeVersion nativeCodeVersion); diff --git a/src/coreclr/vm/util.hpp b/src/coreclr/vm/util.hpp index f2ecac4eac4aa3..62bbca2f21012f 100644 --- a/src/coreclr/vm/util.hpp +++ b/src/coreclr/vm/util.hpp @@ -17,6 +17,7 @@ #include "xclrdata.h" #include "posterror.h" #include +#include "minipal/time.h" #ifndef DACCESS_COMPILE #if defined(TARGET_WINDOWS) && defined(TARGET_ARM64) @@ -797,8 +798,8 @@ class NormalizedTimer static const int64_t NormalizedTicksPerSecond = 10000000 /* 100ns ticks per second (1e7) */; static Volatile s_frequency; - LARGE_INTEGER startTimestamp; - LARGE_INTEGER stopTimestamp; + int64_t startTimestamp; + int64_t stopTimestamp; #if _DEBUG bool isRunning = false; @@ -811,15 +812,14 @@ class NormalizedTimer if (s_frequency.Load() == -1) { double frequency; - LARGE_INTEGER qpfValue; - QueryPerformanceFrequency(&qpfValue); - frequency = static_cast(qpfValue.QuadPart); + int64_t qpfValue = minipal_hires_tick_frequency(); + frequency = static_cast(qpfValue); frequency /= NormalizedTicksPerSecond; s_frequency.Store(frequency); } - startTimestamp.QuadPart = 0; - startTimestamp.QuadPart = 0; + startTimestamp = 0; + stopTimestamp = 0; } // ====================================================================================== @@ -829,7 +829,7 @@ class NormalizedTimer { LIMITED_METHOD_CONTRACT; _ASSERTE(!isRunning); - QueryPerformanceCounter(&startTimestamp); + startTimestamp = minipal_hires_ticks(); #if _DEBUG isRunning = true; @@ -843,7 +843,7 @@ class NormalizedTimer { LIMITED_METHOD_CONTRACT; _ASSERTE(isRunning); - QueryPerformanceCounter(&stopTimestamp); + stopTimestamp = minipal_hires_ticks(); #if _DEBUG isRunning = false; @@ -859,9 +859,9 @@ class NormalizedTimer { LIMITED_METHOD_CONTRACT; _ASSERTE(!isRunning); - _ASSERTE(startTimestamp.QuadPart > 0); - _ASSERTE(stopTimestamp.QuadPart > 0); - return static_cast((stopTimestamp.QuadPart - startTimestamp.QuadPart) / s_frequency); + _ASSERTE(startTimestamp > 0); + _ASSERTE(stopTimestamp > 0); + return static_cast((stopTimestamp - startTimestamp) / s_frequency); } }; diff --git a/src/coreclr/vm/yieldprocessornormalized.cpp b/src/coreclr/vm/yieldprocessornormalized.cpp index 258e30d634c7ce..7901bd024c3145 100644 --- a/src/coreclr/vm/yieldprocessornormalized.cpp +++ b/src/coreclr/vm/yieldprocessornormalized.cpp @@ -3,7 +3,7 @@ #include "common.h" #include "yieldprocessornormalized.h" - +#include "minipal/time.h" #include "finalizerthread.h" diff --git a/src/coreclr/vm/yieldprocessornormalizedshared.cpp b/src/coreclr/vm/yieldprocessornormalizedshared.cpp index dc939ee9f8d45e..55acce2666bff5 100644 --- a/src/coreclr/vm/yieldprocessornormalizedshared.cpp +++ b/src/coreclr/vm/yieldprocessornormalizedshared.cpp @@ -9,40 +9,20 @@ enum class NormalizationState : uint8_t }; static const int NsPerYieldMeasurementCount = 8; -static const unsigned int MeasurementPeriodMs = 4000; +static const int64_t MeasurementPeriodMs = 4000; static const unsigned int NsPerS = 1000 * 1000 * 1000; static NormalizationState s_normalizationState = NormalizationState::Uninitialized; -static unsigned int s_previousNormalizationTimeMs; +static int64_t s_previousNormalizationTimeMs; -static uint64_t s_performanceCounterTicksPerS; +static int64_t s_performanceCounterTicksPerS; static double s_nsPerYieldMeasurements[NsPerYieldMeasurementCount]; static int s_nextMeasurementIndex; static double s_establishedNsPerYield = YieldProcessorNormalization::TargetNsPerNormalizedYield; void RhEnableFinalization(); -inline unsigned int GetTickCountPortable() -{ -#ifdef FEATURE_NATIVEAOT - return (unsigned int)PalGetTickCount64(); -#else - return GetTickCount(); -#endif -} - -static uint64_t GetPerformanceCounter() -{ -#ifdef FEATURE_NATIVEAOT - return PalQueryPerformanceCounter(); -#else - LARGE_INTEGER li; - QueryPerformanceCounter(&li); - return li.QuadPart; -#endif -} - static unsigned int DetermineMeasureDurationUs() { CONTRACTL @@ -60,8 +40,8 @@ static unsigned int DetermineMeasureDurationUs() // On some systems, querying the high performance counter has relatively significant overhead. Increase the measure duration // if the overhead seems high relative to the measure duration. unsigned int measureDurationUs = 1; - uint64_t startTicks = GetPerformanceCounter(); - uint64_t elapsedTicks = GetPerformanceCounter() - startTicks; + int64_t startTicks = minipal_hires_ticks(); + int64_t elapsedTicks = minipal_hires_ticks() - startTicks; if (elapsedTicks >= s_performanceCounterTicksPerS * measureDurationUs * (1000 / 4) / NsPerS) // elapsed >= 1/4 of the measure duration { measureDurationUs *= 4; @@ -84,17 +64,17 @@ static double MeasureNsPerYield(unsigned int measureDurationUs) _ASSERTE(s_normalizationState != NormalizationState::Failed); int yieldCount = (int)(measureDurationUs * 1000 / s_establishedNsPerYield) + 1; - uint64_t ticksPerS = s_performanceCounterTicksPerS; - uint64_t measureDurationTicks = ticksPerS * measureDurationUs / (1000 * 1000); + int64_t ticksPerS = s_performanceCounterTicksPerS; + int64_t measureDurationTicks = ticksPerS * measureDurationUs / (1000 * 1000); - uint64_t startTicks = GetPerformanceCounter(); + int64_t startTicks = minipal_hires_ticks(); for (int i = 0; i < yieldCount; ++i) { System_YieldProcessor(); } - uint64_t elapsedTicks = GetPerformanceCounter() - startTicks; + int64_t elapsedTicks = minipal_hires_ticks() - startTicks; while (elapsedTicks < measureDurationTicks) { int nextYieldCount = @@ -107,7 +87,7 @@ static double MeasureNsPerYield(unsigned int measureDurationUs) System_YieldProcessor(); } - elapsedTicks = GetPerformanceCounter() - startTicks; + elapsedTicks = minipal_hires_ticks() - startTicks; yieldCount += nextYieldCount; } @@ -138,7 +118,7 @@ void YieldProcessorNormalization::PerformMeasurement() double latestNsPerYield; if (s_normalizationState == NormalizationState::Initialized) { - if (GetTickCountPortable() - s_previousNormalizationTimeMs < MeasurementPeriodMs) + if (minipal_lowres_ticks() - s_previousNormalizationTimeMs < MeasurementPeriodMs) { return; } @@ -155,10 +135,10 @@ void YieldProcessorNormalization::PerformMeasurement() else if (s_normalizationState == NormalizationState::Uninitialized) { #ifdef FEATURE_NATIVEAOT - if ((s_performanceCounterTicksPerS = PalQueryPerformanceFrequency()) < 1000 * 1000) + if ((s_performanceCounterTicksPerS = minipal_hires_tick_frequency()) < 1000 * 1000) #else - LARGE_INTEGER li; - if (!QueryPerformanceFrequency(&li) || li.QuadPart < 1000 * 1000) + int64_t freq = minipal_hires_tick_frequency(); + if (freq < 1000 * 1000) #endif { // High precision clock not available or clock resolution is too low, resort to defaults @@ -167,7 +147,7 @@ void YieldProcessorNormalization::PerformMeasurement() } #ifndef FEATURE_NATIVEAOT - s_performanceCounterTicksPerS = li.QuadPart; + s_performanceCounterTicksPerS = freq; #endif unsigned int measureDurationUs = DetermineMeasureDurationUs(); @@ -223,7 +203,7 @@ void YieldProcessorNormalization::PerformMeasurement() GCHeapUtilities::GetGCHeap()->SetYieldProcessorScalingFactor((float)yieldsPerNormalizedYield); - s_previousNormalizationTimeMs = GetTickCountPortable(); + s_previousNormalizationTimeMs = (unsigned int)minipal_lowres_ticks(); s_normalizationState = NormalizationState::Initialized; s_isMeasurementScheduled = false; } @@ -242,7 +222,7 @@ void YieldProcessorNormalization::ScheduleMeasurementIfNecessary() NormalizationState normalizationState = VolatileLoadWithoutBarrier(&s_normalizationState); if (normalizationState == NormalizationState::Initialized) { - if (GetTickCountPortable() - s_previousNormalizationTimeMs < MeasurementPeriodMs) + if (minipal_lowres_ticks() - s_previousNormalizationTimeMs < MeasurementPeriodMs) { return; } diff --git a/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetLowResolutionTimestamp.cs b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetLowResolutionTimestamp.cs new file mode 100644 index 00000000000000..4b369cf863a65c --- /dev/null +++ b/src/libraries/Common/src/Interop/Unix/System.Native/Interop.GetLowResolutionTimestamp.cs @@ -0,0 +1,14 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Sys + { + [LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetLowResolutionTimestamp")] + [SuppressGCTransition] + internal static partial long GetLowResolutionTimestamp(); + } +} 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 00c967896588b8..6a01db94332420 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 @@ -9,6 +9,6 @@ internal static partial class Sys { [LibraryImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetTimestamp")] [SuppressGCTransition] - internal static partial ulong GetTimestamp(); + internal static partial long GetTimestamp(); } } diff --git a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems index 9f4af443787195..cea0562929595a 100644 --- a/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems +++ b/src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems @@ -1880,6 +1880,9 @@ Common\Interop\Windows\Kernel32\Interop.GetCurrentThreadId.cs + + Interop\Windows\Kernel32\Interop.GetTickCount64.cs + Common\Interop\Windows\Kernel32\Interop.GetFileAttributesEx.cs @@ -2401,6 +2404,9 @@ Common\Interop\Unix\System.Native\Interop.GetSystemTimeAsTicks.cs + + Common\Interop\Unix\System.Native\Interop.GetLowResolutionTimestamp.cs + Common\Interop\Unix\System.Native\Interop.GetTimestamp.cs 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 487923148aa0df..77f7fa43d326ba 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 @@ -13,7 +13,7 @@ private static long QueryPerformanceFrequency() private static long QueryPerformanceCounter() { - return (long)Interop.Sys.GetTimestamp(); + return Interop.Sys.GetTimestamp(); } } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.UnixOrBrowser.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.UnixOrBrowser.cs index 6dbbfe272b25b6..75128d7e22886c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.UnixOrBrowser.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.UnixOrBrowser.cs @@ -93,5 +93,9 @@ public static ProcessCpuUsage CpuUsage return new ProcessCpuUsage { UserTime = new TimeSpan((long)userTime100Nanoseconds), PrivilegedTime = new TimeSpan((long)kernelTime100Nanoseconds) }; } } + + /// Gets the number of milliseconds elapsed since the system started. + /// A 64-bit signed integer containing the amount of time in milliseconds that has passed since the last time the computer was started. + public static long TickCount64 => Interop.Sys.GetLowResolutionTimestamp(); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.Windows.cs index 314a73b4fbdceb..a84d9218acb1d6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.Windows.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.Windows.cs @@ -374,5 +374,9 @@ public static ProcessCpuUsage CpuUsage new ProcessCpuUsage { UserTime = new TimeSpan(procUserTime), PrivilegedTime = new TimeSpan(procKernelTime) } : new ProcessCpuUsage { UserTime = TimeSpan.Zero, PrivilegedTime = TimeSpan.Zero }; } + + /// Gets the number of milliseconds elapsed since the system started. + /// A 64-bit signed integer containing the amount of time in milliseconds that has passed since the last time the computer was started. + public static long TickCount64 => (long)Interop.Kernel32.GetTickCount64(); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Environment.cs b/src/libraries/System.Private.CoreLib/src/System/Environment.cs index 1f9e9a77d74300..81cd182e7da155 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Environment.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Environment.cs @@ -249,6 +249,10 @@ public static int SystemPageSize } } + /// Gets the number of milliseconds elapsed since the system started. + /// A 32-bit signed integer containing the amount of time in milliseconds that has passed since the last time the computer was started. + public static int TickCount => (int)TickCount64; + private static bool ValidateAndConvertRegistryTarget(EnvironmentVariableTarget target) { Debug.Assert(target != EnvironmentVariableTarget.Process); diff --git a/src/mono/System.Private.CoreLib/src/System/Environment.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Environment.Mono.cs index 91d6ccef63e2ea..97f62e4a1fd033 100644 --- a/src/mono/System.Private.CoreLib/src/System/Environment.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Environment.Mono.cs @@ -24,18 +24,6 @@ public static extern int ExitCode [MethodImplAttribute(MethodImplOptions.InternalCall)] private static extern int GetProcessorCount(); - public static extern int TickCount - { - [MethodImplAttribute(MethodImplOptions.InternalCall)] - get; - } - - public static extern long TickCount64 - { - [MethodImplAttribute(MethodImplOptions.InternalCall)] - get; - } - [MethodImplAttribute(MethodImplOptions.InternalCall)] [DoesNotReturn] public static extern void Exit(int exitCode); diff --git a/src/mono/cmake/config.h.in b/src/mono/cmake/config.h.in index 8ac0c0f7c3c290..b5224211265cdb 100644 --- a/src/mono/cmake/config.h.in +++ b/src/mono/cmake/config.h.in @@ -263,21 +263,9 @@ /* CLOCK_MONOTONIC */ #cmakedefine HAVE_CLOCK_MONOTONIC 1 -/* CLOCK_MONOTONIC_COARSE */ -#cmakedefine HAVE_CLOCK_MONOTONIC_COARSE 1 - /* clockid_t */ #cmakedefine HAVE_CLOCKID_T 1 -/* mach_absolute_time */ -#cmakedefine HAVE_MACH_ABSOLUTE_TIME 1 - -/* gethrtime */ -#cmakedefine HAVE_GETHRTIME 1 - -/* read_real_time */ -#cmakedefine HAVE_READ_REAL_TIME 1 - /* Define to 1 if you have the `clock_nanosleep' function. */ #cmakedefine HAVE_CLOCK_NANOSLEEP 1 diff --git a/src/mono/cmake/configure.cmake b/src/mono/cmake/configure.cmake index b5cf1c625e4bb3..6b9e021f1437bc 100644 --- a/src/mono/cmake/configure.cmake +++ b/src/mono/cmake/configure.cmake @@ -113,7 +113,6 @@ check_function_exists(clock_gettime HAVE_CLOCK_GETTIME) check_symbol_exists(madvise "sys/mman.h" HAVE_MADVISE) check_symbol_exists(pthread_mutexattr_setprotocol "pthread.h" HAVE_DECL_PTHREAD_MUTEXATTR_SETPROTOCOL) check_symbol_exists(CLOCK_MONOTONIC "time.h" HAVE_CLOCK_MONOTONIC) -check_symbol_exists(CLOCK_MONOTONIC_COARSE "time.h" HAVE_CLOCK_MONOTONIC_COARSE) check_symbol_exists(sys_signame "signal.h" HAVE_SYSSIGNAME) check_symbol_exists(pthread_jit_write_protect_np "pthread.h" HAVE_PTHREAD_JIT_WRITE_PROTECT_NP) @@ -277,9 +276,6 @@ elseif(HOST_WASI) set(HAVE_MKSTEMP 0) set(HAVE_BACKTRACE_SYMBOLS 0) set(HAVE_GETPID 0) - set(HAVE_MACH_ABSOLUTE_TIME 0) - set(HAVE_GETHRTIME 0) - set(HAVE_READ_REAL_TIME 0) set(HAVE_SCHED_GETAFFINITY 0) set(HAVE_SCHED_SETAFFINITY 0) set(HAVE_GETHOSTBYNAME 0) diff --git a/src/mono/mono/eventpipe/ep-rt-mono.c b/src/mono/mono/eventpipe/ep-rt-mono.c index 196b183a2d7971..a6ea9092673d29 100644 --- a/src/mono/mono/eventpipe/ep-rt-mono.c +++ b/src/mono/mono/eventpipe/ep-rt-mono.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -329,27 +330,19 @@ ep_rt_mono_thread_exited (void) } } -#ifdef HOST_WIN32 int64_t ep_rt_mono_perf_counter_query (void) { - LARGE_INTEGER value; - if (QueryPerformanceCounter (&value)) - return (int64_t)value.QuadPart; - else - return 0; + return minipal_hires_ticks(); } int64_t ep_rt_mono_perf_frequency_query (void) { - LARGE_INTEGER value; - if (QueryPerformanceFrequency (&value)) - return (int64_t)value.QuadPart; - else - return 0; + return minipal_hires_tick_frequency(); } +#ifdef HOST_WIN32 void ep_rt_mono_system_time_get (EventPipeSystemTime *system_time) { @@ -385,19 +378,12 @@ ep_rt_mono_system_timestamp_get (void) #include #endif // HAVE_SYS_TIME_H -#if HAVE_MACH_ABSOLUTE_TIME -#include -static mono_lazy_init_t _ep_rt_mono_time_base_info_init = MONO_LAZY_INIT_STATUS_NOT_INITIALIZED; -static mach_timebase_info_data_t _ep_rt_mono_time_base_info = {0}; -#endif - #ifdef HAVE_LOCALTIME_R #define HAVE_GMTIME_R 1 #endif static const int64_t SECS_BETWEEN_1601_AND_1970_EPOCHS = 11644473600LL; static const int64_t SECS_TO_100NS = 10000000; -static const int64_t SECS_TO_NS = 1000000000; static const int64_t MSECS_TO_MIS = 1000; /* clock_gettime () is found by configure on Apple builds, but its only present from ios 10, macos 10.12, tvos 10 and watchos 3 */ @@ -409,67 +395,12 @@ static const int64_t MSECS_TO_MIS = 1000; static const int64_t MISECS_TO_NS = 1000; #endif -static -void -time_base_info_lazy_init (void); - static int64_t system_time_to_int64 ( time_t sec, long nsec); -#if HAVE_MACH_ABSOLUTE_TIME -static -void -time_base_info_lazy_init (void) -{ - kern_return_t result = mach_timebase_info (&_ep_rt_mono_time_base_info); - if (result != KERN_SUCCESS) - memset (&_ep_rt_mono_time_base_info, 0, sizeof (_ep_rt_mono_time_base_info)); -} -#endif - -int64_t -ep_rt_mono_perf_counter_query (void) -{ -#if HAVE_MACH_ABSOLUTE_TIME - return (int64_t)mach_absolute_time (); -#elif HAVE_CLOCK_MONOTONIC - struct timespec ts; - int result = clock_gettime (CLOCK_MONOTONIC, &ts); - if (result == 0) - return ((int64_t)(ts.tv_sec) * (int64_t)(SECS_TO_NS)) + (int64_t)(ts.tv_nsec); -#else - #error "ep_rt_mono_perf_counter_get requires either mach_absolute_time () or clock_gettime (CLOCK_MONOTONIC) to be supported." -#endif - return 0; -} - -int64_t -ep_rt_mono_perf_frequency_query (void) -{ -#if HAVE_MACH_ABSOLUTE_TIME - // (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. - mono_lazy_initialize (&_ep_rt_mono_time_base_info_init, time_base_info_lazy_init); - if (_ep_rt_mono_time_base_info.denom == 0 || _ep_rt_mono_time_base_info.numer == 0) - return 0; - return ((int64_t)(SECS_TO_NS) * (int64_t)(_ep_rt_mono_time_base_info.denom)) / (int64_t)(_ep_rt_mono_time_base_info.numer); -#elif HAVE_CLOCK_MONOTONIC - // 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 (int64_t)(SECS_TO_NS); -#else - #error "ep_rt_mono_perf_frequency_query requires either mach_absolute_time () or clock_gettime (CLOCK_MONOTONIC) to be supported." -#endif - return 0; -} - void ep_rt_mono_system_time_get (EventPipeSystemTime *system_time) { diff --git a/src/mono/mono/metadata/icall-decl.h b/src/mono/mono/metadata/icall-decl.h index ebce337af7b1a3..9c5e9f8c56490b 100644 --- a/src/mono/mono/metadata/icall-decl.h +++ b/src/mono/mono/metadata/icall-decl.h @@ -118,8 +118,6 @@ ICALL_EXPORT double ves_icall_System_Math_FusedMultiplyAdd (double, double, doub ICALL_EXPORT float ves_icall_System_MathF_Log2 (float); ICALL_EXPORT float ves_icall_System_MathF_FusedMultiplyAdd (float, float, float); ICALL_EXPORT gint32 ves_icall_System_Environment_get_ProcessorCount (void); -ICALL_EXPORT gint32 ves_icall_System_Environment_get_TickCount (void); -ICALL_EXPORT gint64 ves_icall_System_Environment_get_TickCount64 (void); ICALL_EXPORT gint64 ves_icall_System_GC_GetTotalMemory (MonoBoolean forceCollection); ICALL_EXPORT int ves_icall_System_GC_GetCollectionCount (int); ICALL_EXPORT int ves_icall_System_GC_GetMaxGeneration (void); diff --git a/src/mono/mono/metadata/icall-def.h b/src/mono/mono/metadata/icall-def.h index 2661ebd4bc0989..acb70083ad990c 100644 --- a/src/mono/mono/metadata/icall-def.h +++ b/src/mono/mono/metadata/icall-def.h @@ -203,8 +203,6 @@ HANDLES(ENV_1a, "FailFast", ves_icall_System_Environment_FailFast, void, 3, (Mon HANDLES(ENV_2, "GetCommandLineArgs", ves_icall_System_Environment_GetCommandLineArgs, MonoArray, 0, ()) NOHANDLES(ICALL(ENV_4, "GetProcessorCount", ves_icall_System_Environment_get_ProcessorCount)) NOHANDLES(ICALL(ENV_9, "get_ExitCode", mono_environment_exitcode_get)) -NOHANDLES(ICALL(ENV_15, "get_TickCount", ves_icall_System_Environment_get_TickCount)) -NOHANDLES(ICALL(ENV_15a, "get_TickCount64", ves_icall_System_Environment_get_TickCount64)) NOHANDLES(ICALL(ENV_20, "set_ExitCode", mono_environment_exitcode_set)) ICALL_TYPE(GC, "System.GC", GC_4a) diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index 7b095b3ab8e534..69b2cf2813dbd3 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -6244,19 +6244,6 @@ ves_icall_System_Environment_FailFast (MonoStringHandle message, MonoExceptionHa abort (); } -gint32 -ves_icall_System_Environment_get_TickCount (void) -{ - /* this will overflow after ~24 days */ - return (gint32) (mono_msec_boottime () & 0xffffffff); -} - -gint64 -ves_icall_System_Environment_get_TickCount64 (void) -{ - return mono_msec_boottime (); -} - gpointer ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method, MonoError *error) { diff --git a/src/mono/mono/utils/mono-time.c b/src/mono/mono/utils/mono-time.c index 2a89bd9d3d0772..bf047cd01a497f 100644 --- a/src/mono/mono/utils/mono-time.c +++ b/src/mono/mono/utils/mono-time.c @@ -15,19 +15,10 @@ #include #endif -#ifdef HOST_DARWIN -#include -#include -#endif - #include #include -#if HAVE_MACH_ABSOLUTE_TIME -#include -#endif - #define MTICKS_PER_SEC (10 * 1000 * 1000) typedef enum _TimeConversionConstants @@ -51,18 +42,6 @@ mono_msec_ticks (void) #ifdef HOST_WIN32 #include -#ifndef _MSC_VER -/* we get "error: implicit declaration of function 'GetTickCount64'" */ -WINBASEAPI ULONGLONG WINAPI GetTickCount64(void); -#endif - -gint64 -mono_msec_boottime (void) -{ - /* GetTickCount () is reportedly monotonic */ - return GetTickCount64 (); -} - /* Returns the number of 100ns ticks from unspecified time: this should be monotonic */ gint64 mono_100ns_ticks (void) @@ -113,69 +92,6 @@ MONO_RESTORE_WARNING #include -/* Returns the number of milliseconds from boot time: this should be monotonic */ -/* Adapted from CoreCLR: https://github.com/dotnet/runtime/blob/402aa8584ed18792d6bc6ed1869f7c31b38f8139/src/coreclr/pal/src/misc/time.cpp */ -gint64 -mono_msec_boottime (void) -{ - /* clock_gettime () is found by configure on Apple builds, but its only present from ios 10, macos 10.12, tvos 10 and watchos 3 */ -#if ((defined(HAVE_CLOCK_MONOTONIC_COARSE) || defined(HAVE_CLOCK_MONOTONIC)) && !(defined(TARGET_IOS) || defined(TARGET_OSX) || defined(TARGET_WATCHOS) || defined(TARGET_TVOS))) - clockid_t clockType = - /* emscripten exposes CLOCK_MONOTONIC_COARSE but doesn't implement it */ -#if defined(HAVE_CLOCK_MONOTONIC_COARSE) && !defined(TARGET_WASM) - CLOCK_MONOTONIC_COARSE; /* good enough resolution, fastest speed */ -#else - CLOCK_MONOTONIC; -#endif - struct timespec ts; - if (clock_gettime (clockType, &ts) != 0) { - g_error ("clock_gettime(CLOCK_MONOTONIC*) failed; errno is %d", errno, strerror (errno)); - return 0; - } - return (ts.tv_sec * tccSecondsToMillieSeconds) + (ts.tv_nsec / tccMillieSecondsToNanoSeconds); - -#elif HAVE_MACH_ABSOLUTE_TIME - static gboolean timebase_inited; - static mach_timebase_info_data_t s_TimebaseInfo; - - if (!timebase_inited) { - kern_return_t machRet; - mach_timebase_info_data_t tmp; - machRet = mach_timebase_info (&tmp); - g_assert (machRet == KERN_SUCCESS); - /* Assume memcpy works correctly if ran concurrently */ - memcpy (&s_TimebaseInfo, &tmp, sizeof (mach_timebase_info_data_t)); - mono_memory_barrier (); - timebase_inited = TRUE; - } else { - // This barrier prevents reading s_TimebaseInfo before reading timebase_inited. - mono_memory_barrier (); - } - return (mach_absolute_time () * s_TimebaseInfo.numer / s_TimebaseInfo.denom) / tccMillieSecondsToNanoSeconds; - -#elif HAVE_GETHRTIME - return (gint64)(gethrtime () / tccMillieSecondsToNanoSeconds); - -#elif HAVE_READ_REAL_TIME - timebasestruct_t tb; - read_real_time (&tb, TIMEBASE_SZ); - if (time_base_to_time (&tb, TIMEBASE_SZ) != 0) { - g_error ("time_base_to_time() failed; errno is %d (%s)", errno, strerror (errno)); - return 0; - } - return (tb.tb_high * tccSecondsToMillieSeconds) + (tb.tb_low / tccMillieSecondsToNanoSeconds); - -#else - struct timeval tv; - if (gettimeofday (&tv, NULL) == -1) { - g_error ("gettimeofday() failed; errno is %d (%s)", errno, strerror (errno)); - return 0; - } - return (tv.tv_sec * tccSecondsToMillieSeconds) + (tv.tv_usec / tccMillieSecondsToMicroSeconds); - -#endif /* HAVE_CLOCK_MONOTONIC */ -} - /* Returns the number of 100ns ticks from unspecified time: this should be monotonic */ gint64 mono_100ns_ticks (void) diff --git a/src/mono/mono/utils/mono-time.h b/src/mono/mono/utils/mono-time.h index 685f2bc76e31ef..b62352ab26a8cf 100644 --- a/src/mono/mono/utils/mono-time.h +++ b/src/mono/mono/utils/mono-time.h @@ -11,11 +11,6 @@ #include #endif -/* Returns the number of milliseconds from boot time: this should be monotonic - * - * Prefer to use mono_msec_ticks for elapsed time calculation. */ -gint64 mono_msec_boottime (void); - /* Returns the number of milliseconds ticks from unspecified time: this should be monotonic */ MONO_COMPONENT_API gint64 mono_msec_ticks (void); diff --git a/src/native/libs/System.Native/entrypoints.c b/src/native/libs/System.Native/entrypoints.c index a133f59b179e2d..fb6d78ceef3c55 100644 --- a/src/native/libs/System.Native/entrypoints.c +++ b/src/native/libs/System.Native/entrypoints.c @@ -255,6 +255,7 @@ static const Entry s_sysNative[] = DllImportEntry(SystemNative_UTimensat) DllImportEntry(SystemNative_FUTimens) DllImportEntry(SystemNative_GetTimestamp) + DllImportEntry(SystemNative_GetLowResolutionTimestamp) DllImportEntry(SystemNative_GetBootTimeTicks) DllImportEntry(SystemNative_GetCpuUtilization) DllImportEntry(SystemNative_GetPwUidR) diff --git a/src/native/libs/System.Native/pal_time.c b/src/native/libs/System.Native/pal_time.c index 488c49776fd9f3..0f37ddbe006418 100644 --- a/src/native/libs/System.Native/pal_time.c +++ b/src/native/libs/System.Native/pal_time.c @@ -12,9 +12,7 @@ #include #include #include -#if HAVE_CLOCK_GETTIME_NSEC_NP -#include -#endif +#include enum { @@ -81,19 +79,14 @@ int32_t SystemNative_FUTimens(intptr_t fd, TimeSpec* times) return result; } -uint64_t SystemNative_GetTimestamp(void) +int64_t SystemNative_GetTimestamp(void) { -#if HAVE_CLOCK_GETTIME_NSEC_NP - return clock_gettime_nsec_np(CLOCK_UPTIME_RAW); -#else - struct timespec ts; - - int result = clock_gettime(CLOCK_MONOTONIC, &ts); - assert(result == 0); // only possible errors are if MONOTONIC isn't supported or &ts is an invalid address - (void)result; // suppress unused parameter warning in release builds + return minipal_hires_ticks(); +} - return ((uint64_t)(ts.tv_sec) * SecondsToNanoSeconds) + (uint64_t)(ts.tv_nsec); -#endif +int64_t SystemNative_GetLowResolutionTimestamp(void) +{ + return minipal_lowres_ticks(); } int64_t SystemNative_GetBootTimeTicks(void) @@ -141,7 +134,7 @@ double SystemNative_GetCpuUtilization(ProcessCpuInformation* previousCpuInfo) ((uint64_t)(resUsage.ru_utime.tv_usec) * MicroSecondsToNanoSeconds); } - uint64_t currentTime = SystemNative_GetTimestamp(); + uint64_t currentTime = (uint64_t)minipal_hires_ticks(); uint64_t lastRecordedCurrentTime = previousCpuInfo->lastRecordedCurrentTime; uint64_t lastRecordedKernelTime = previousCpuInfo->lastRecordedKernelTime; diff --git a/src/native/libs/System.Native/pal_time.h b/src/native/libs/System.Native/pal_time.h index 26db2c20c102ef..dad3cf3c8e847e 100644 --- a/src/native/libs/System.Native/pal_time.h +++ b/src/native/libs/System.Native/pal_time.h @@ -37,7 +37,12 @@ PALEXPORT int32_t SystemNative_FUTimens(intptr_t fd, TimeSpec* times); /** * Gets a high-resolution timestamp that can be used for time-interval measurements. */ -PALEXPORT uint64_t SystemNative_GetTimestamp(void); +PALEXPORT int64_t SystemNative_GetTimestamp(void); + +/** + * Gets a low-resolution timestamp in milliseconds. + */ + PALEXPORT int64_t SystemNative_GetLowResolutionTimestamp(void); /** * Gets system boot time ticks. (Linux only) diff --git a/src/native/minipal/configure.cmake b/src/native/minipal/configure.cmake index e9560786df50a1..473c4f8124c521 100644 --- a/src/native/minipal/configure.cmake +++ b/src/native/minipal/configure.cmake @@ -11,6 +11,8 @@ check_function_exists(fsync HAVE_FSYNC) check_symbol_exists(arc4random_buf "stdlib.h" HAVE_ARC4RANDOM_BUF) check_symbol_exists(O_CLOEXEC fcntl.h HAVE_O_CLOEXEC) +check_symbol_exists(CLOCK_MONOTONIC time.h HAVE_CLOCK_MONOTONIC) +check_symbol_exists(CLOCK_MONOTONIC_COARSE time.h HAVE_CLOCK_MONOTONIC_COARSE) check_symbol_exists(clock_gettime_nsec_np time.h HAVE_CLOCK_GETTIME_NSEC_NP) if(CMAKE_C_BYTE_ORDER STREQUAL "BIG_ENDIAN") diff --git a/src/native/minipal/minipalconfig.h.in b/src/native/minipal/minipalconfig.h.in index e5207103dddf0f..1ecd683be425c2 100644 --- a/src/native/minipal/minipalconfig.h.in +++ b/src/native/minipal/minipalconfig.h.in @@ -6,6 +6,8 @@ #cmakedefine01 HAVE_HWPROBE_H #cmakedefine01 HAVE_O_CLOEXEC #cmakedefine01 HAVE_SYSCTLBYNAME +#cmakedefine01 HAVE_CLOCK_MONOTONIC +#cmakedefine01 HAVE_CLOCK_MONOTONIC_COARSE #cmakedefine01 HAVE_CLOCK_GETTIME_NSEC_NP #cmakedefine01 BIGENDIAN #cmakedefine01 HAVE_BCRYPT_H diff --git a/src/native/minipal/time.c b/src/native/minipal/time.c index 20c117be5ff48c..844e10287f4144 100644 --- a/src/native/minipal/time.c +++ b/src/native/minipal/time.c @@ -12,22 +12,32 @@ int64_t minipal_hires_ticks() { LARGE_INTEGER ts; - QueryPerformanceCounter(&ts); + BOOL ret; + ret = QueryPerformanceCounter(&ts); + assert(ret); // The function is documented to never fail on Windows XP+. return ts.QuadPart; } int64_t minipal_hires_tick_frequency() { LARGE_INTEGER ts; - QueryPerformanceFrequency(&ts); + BOOL ret; + ret = QueryPerformanceFrequency(&ts); + assert(ret); // The function is documented to never fail on Windows XP+. return ts.QuadPart; } +int64_t minipal_lowres_ticks() +{ + return GetTickCount64(); +} + #else // HOST_WINDOWS #include "minipalconfig.h" -#include // nanosleep +#include +#include #include inline static void YieldProcessor(void); @@ -56,6 +66,8 @@ inline static void YieldProcessor(void) } #define tccSecondsToNanoSeconds 1000000000 // 10^9 +#define tccSecondsToMilliSeconds 1000 // 10^3 +#define tccMilliSecondsToNanoSeconds 1000000 // 10^6 int64_t minipal_hires_tick_frequency(void) { return tccSecondsToNanoSeconds; @@ -65,7 +77,7 @@ int64_t minipal_hires_ticks(void) { #if HAVE_CLOCK_GETTIME_NSEC_NP return (int64_t)clock_gettime_nsec_np(CLOCK_UPTIME_RAW); -#else +#elif HAVE_CLOCK_MONOTONIC struct timespec ts; int result = clock_gettime(CLOCK_MONOTONIC, &ts); if (result != 0) @@ -74,6 +86,42 @@ int64_t minipal_hires_ticks(void) } return ((int64_t)(ts.tv_sec) * (int64_t)(tccSecondsToNanoSeconds)) + (int64_t)(ts.tv_nsec); +#else + #error "minipal_hires_ticks requires clock_gettime_nsec_np or clock_gettime to be supported." +#endif +} + +int64_t minipal_lowres_ticks(void) +{ +#if HAVE_CLOCK_GETTIME_NSEC_NP + return (int64_t)clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / (int64_t)(tccMilliSecondsToNanoSeconds); +#elif HAVE_CLOCK_MONOTONIC + struct timespec ts; + + // emscripten exposes CLOCK_MONOTONIC_COARSE but doesn't implement it +#if HAVE_CLOCK_MONOTONIC_COARSE && !defined(__EMSCRIPTEN__) + // CLOCK_MONOTONIC_COARSE has enough precision for GetTickCount but + // doesn't have the same overhead as CLOCK_MONOTONIC. This allows + // overall higher throughput. See dotnet/coreclr#2257 for more details. + + const clockid_t clockType = CLOCK_MONOTONIC_COARSE; +#else + const clockid_t clockType = CLOCK_MONOTONIC; +#endif + + int result = clock_gettime(clockType, &ts); + if (result != 0) + { +#if HAVE_CLOCK_MONOTONIC_COARSE && !defined(__EMSCRIPTEN__) + assert(!"clock_gettime(CLOCK_MONOTONIC_COARSE) failed"); +#else + assert(!"clock_gettime(CLOCK_MONOTONIC) failed"); +#endif + } + + return ((int64_t)(ts.tv_sec) * (int64_t)(tccSecondsToMilliSeconds)) + ((int64_t)(ts.tv_nsec) / (int64_t)(tccMilliSecondsToNanoSeconds)); +#else + #error "minipal_lowres_ticks requires clock_gettime_nsec_np or clock_gettime to be supported." #endif } diff --git a/src/native/minipal/time.h b/src/native/minipal/time.h index 27359aa407c754..f0ada2f7f507ce 100644 --- a/src/native/minipal/time.h +++ b/src/native/minipal/time.h @@ -17,6 +17,9 @@ extern "C" // Returns the frequency of high resolution timer ticks in Hz int64_t minipal_hires_tick_frequency(void); + // Returns a low-precision monotonically increasing timer in milliseconds + int64_t minipal_lowres_ticks(void); + // Delays execution of current thread by `usecs` microseconds. // The delay is best-effort and may take longer than desired. // Some delays, depending on OS and duration, could be implemented via busy waiting.