Bug 1391696 - Use GetTickCount64 without a GetProcAddress check in Timestamp_windows.cpp. r=froydnj

MozReview-Commit-ID: 7rkorGQKCOw

--HG--
extra : rebase_source : ff797855d7206e2efa9523591f6d57c8319ed984
This commit is contained in:
Masatoshi Kimura 2017-08-19 03:08:11 +09:00
parent 386be6c6a6
commit e34560fbbc

View File

@ -5,7 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Implement TimeStamp::Now() with QueryPerformanceCounter() controlled with
// values of GetTickCount().
// values of GetTickCount64().
#include "mozilla/MathAlgorithms.h"
#include "mozilla/TimeStamp.h"
@ -69,7 +69,7 @@ static const DWORD kDefaultTimeIncrement = 156001;
* further just referred as [mt], meaning milli-ticks.
*
* This is needed to preserve maximum precision of the performance frequency
* representation. GetTickCount values in milliseconds are multiplied with
* representation. GetTickCount64 values in milliseconds are multiplied with
* frequency per second. Therefor we need to multiply QPC value by 1000 to
* have the same units to allow simple arithmentic with both QPC and GTC.
*/
@ -156,41 +156,8 @@ static CRITICAL_SECTION sTimeStampLock;
// Kept in [mt]
static ULONGLONG sFaultIntoleranceCheckpoint = 0;
// Used only when GetTickCount64 is not available on the platform.
// Last result of GetTickCount call.
//
// Kept in [ms]
static DWORD sLastGTCResult = 0;
// Higher part of the 64-bit value of MozGetTickCount64,
// incremented atomically.
static DWORD sLastGTCRollover = 0;
namespace mozilla {
typedef ULONGLONG (WINAPI* GetTickCount64_t)();
static GetTickCount64_t sGetTickCount64 = nullptr;
// Function protecting GetTickCount result from rolling over,
// result is in [ms]
static ULONGLONG WINAPI
MozGetTickCount64()
{
DWORD GTC = ::GetTickCount();
// Cheaper then CMPXCHG8B
AutoCriticalSection lock(&sTimeStampLock);
// Pull the rollover counter forward only if new value of GTC goes way
// down under the last saved result
if ((sLastGTCResult > GTC) && ((sLastGTCResult - GTC) > (1UL << 30))) {
++sLastGTCRollover;
}
sLastGTCResult = GTC;
return ULONGLONG(sLastGTCRollover) << 32 | sLastGTCResult;
}
// Result is in [mt]
static inline ULONGLONG
PerformanceCounter()
@ -367,7 +334,7 @@ TimeStampValue::CheckQPC(const TimeStampValue& aOther) const
if (duration < sHardFailureLimit) {
// Interval between the two time stamps is very short, consider
// QPC as unstable and record a failure.
uint64_t now = ms2mt(sGetTickCount64());
uint64_t now = ms2mt(GetTickCount64());
AutoCriticalSection lock(&sTimeStampLock);
@ -503,15 +470,6 @@ TimeStamp::Startup()
// Decide which implementation to use for the high-performance timer.
HMODULE kernelDLL = GetModuleHandleW(L"kernel32.dll");
sGetTickCount64 = reinterpret_cast<GetTickCount64_t>(
GetProcAddress(kernelDLL, "GetTickCount64"));
if (!sGetTickCount64) {
// If the platform does not support the GetTickCount64 (Windows XP doesn't),
// then use our fallback implementation based on GetTickCount.
sGetTickCount64 = MozGetTickCount64;
}
InitializeCriticalSectionAndSpinCount(&sTimeStampLock, kLockSpinCount);
sHasStableTSC = HasStableTSC();
@ -520,10 +478,10 @@ TimeStamp::Startup()
LARGE_INTEGER freq;
sUseQPC = ::QueryPerformanceFrequency(&freq);
if (!sUseQPC) {
// No Performance Counter. Fall back to use GetTickCount.
// No Performance Counter. Fall back to use GetTickCount64.
InitResolution();
LOG(("TimeStamp: using GetTickCount"));
LOG(("TimeStamp: using GetTickCount64"));
return;
}
@ -550,7 +508,7 @@ TimeStamp::Now(bool aHighResolution)
// Both values are in [mt] units.
ULONGLONG QPC = useQPC ? PerformanceCounter() : uint64_t(0);
ULONGLONG GTC = ms2mt(sGetTickCount64());
ULONGLONG GTC = ms2mt(GetTickCount64());
return TimeStamp(TimeStampValue(GTC, QPC, useQPC));
}