MFBT_API int64_t BaseTimeDurationPlatformUtils::TicksFromMilliseconds(double aMilliseconds) { double result = ms2mt(aMilliseconds); if (result > INT64_MAX) { return INT64_MAX; } else if (result < INT64_MIN) { return INT64_MIN; } return result; }
static void InitThresholds() { DWORD timeAdjustment = 0, timeIncrement = 0; BOOL timeAdjustmentDisabled; GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, &timeAdjustmentDisabled); LOG(("TimeStamp: timeIncrement=%d [100ns]", timeIncrement)); if (!timeIncrement) { timeIncrement = kDefaultTimeIncrement; } // Ceiling to a millisecond // Example values: 156001, 210000 DWORD timeIncrementCeil = timeIncrement; // Don't want to round up if already rounded, values will be: 156000, 209999 timeIncrementCeil -= 1; // Convert to ms, values will be: 15, 20 timeIncrementCeil /= 10000; // Round up, values will be: 16, 21 timeIncrementCeil += 1; // Convert back to 100ns, values will be: 160000, 210000 timeIncrementCeil *= 10000; // How many milli-ticks has the interval rounded up LONGLONG ticksPerGetTickCountResolutionCeiling = (int64_t(timeIncrementCeil) * sFrequencyPerSec) / 10000LL; // GTC may jump by 32 (2*16) ms in two steps, therefor use the ceiling value. sGTCResolutionThreshold = LONGLONG(kGTCTickLeapTolerance * ticksPerGetTickCountResolutionCeiling); sHardFailureLimit = ms2mt(kHardFailureLimit); sFailureFreeInterval = ms2mt(kFailureFreeInterval); sFailureThreshold = ms2mt(kFailureThreshold); }
TimeDuration TimeDuration::FromMilliseconds(double aMilliseconds) { return TimeDuration::FromTicks(int64_t(ms2mt(aMilliseconds))); }
// If the duration is less then two seconds, perform check of QPC stability // by comparing both GTC and QPC calculated durations of this and aOther. MFBT_API uint64_t TimeStampValue::CheckQPC(const TimeStampValue& aOther) const { uint64_t deltaGTC = mGTC - aOther.mGTC; if (!mHasQPC || !aOther.mHasQPC) { // Both not holding QPC return deltaGTC; } uint64_t deltaQPC = mQPC - aOther.mQPC; if (sHasStableTSC) { // For stable TSC there is no need to check return deltaQPC; } // Check QPC is sane before using it. int64_t diff = DeprecatedAbs(int64_t(deltaQPC) - int64_t(deltaGTC)); if (diff <= sGTCResolutionThreshold) { return deltaQPC; } // Treat absolutely for calibration purposes int64_t duration = DeprecatedAbs(int64_t(deltaGTC)); int64_t overflow = diff - sGTCResolutionThreshold; LOG(("TimeStamp: QPC check after %llums with overflow %1.4fms", mt2ms(duration), mt2ms_f(overflow))); if (overflow <= sFailureThreshold) { // We are in the limit, let go. return deltaQPC; } // QPC deviates, don't use it, since now this method may only return deltaGTC. if (!sUseQPC) { // QPC already disabled, no need to run the fault tolerance algorithm. return deltaGTC; } LOG(("TimeStamp: QPC jittered over failure threshold")); 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()); AutoCriticalSection lock(&sTimeStampLock); if (sFaultIntoleranceCheckpoint && sFaultIntoleranceCheckpoint > now) { // There's already been an error in the last fault intollerant interval. // Time since now to the checkpoint actually holds information on how many // failures there were in the failure free interval we have defined. uint64_t failureCount = (sFaultIntoleranceCheckpoint - now + sFailureFreeInterval - 1) / sFailureFreeInterval; if (failureCount > kMaxFailuresPerInterval) { sUseQPC = false; LOG(("TimeStamp: QPC disabled")); } else { // Move the fault intolerance checkpoint more to the future, prolong it // to reflect the number of detected failures. ++failureCount; sFaultIntoleranceCheckpoint = now + failureCount * sFailureFreeInterval; LOG(("TimeStamp: recording %dth QPC failure", failureCount)); } } else { // Setup fault intolerance checkpoint in the future for first detected error. sFaultIntoleranceCheckpoint = now + sFailureFreeInterval; LOG(("TimeStamp: recording 1st QPC failure")); } } return deltaGTC; }