tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

time_win.cc (31913B)


      1 // Copyright 2012 The Chromium Authors
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 
      6 // Windows Timer Primer
      7 //
      8 // A good article:  http://www.ddj.com/windows/184416651
      9 // A good mozilla bug:  http://bugzilla.mozilla.org/show_bug.cgi?id=363258
     10 //
     11 // The default windows timer, GetSystemTimeAsFileTime is not very precise.
     12 // It is only good to ~15.5ms.
     13 //
     14 // QueryPerformanceCounter is the logical choice for a high-precision timer.
     15 // However, it is known to be buggy on some hardware.  Specifically, it can
     16 // sometimes "jump".  On laptops, QPC can also be very expensive to call.
     17 // It's 3-4x slower than timeGetTime() on desktops, but can be 10x slower
     18 // on laptops.  A unittest exists which will show the relative cost of various
     19 // timers on any system.
     20 //
     21 // The next logical choice is timeGetTime().  timeGetTime has a precision of
     22 // 1ms, but only if you call APIs (timeBeginPeriod()) which affect all other
     23 // applications on the system.  By default, precision is only 15.5ms.
     24 // Unfortunately, we don't want to call timeBeginPeriod because we don't
     25 // want to affect other applications.  Further, on mobile platforms, use of
     26 // faster multimedia timers can hurt battery life.  See the intel
     27 // article about this here:
     28 // http://softwarecommunity.intel.com/articles/eng/1086.htm
     29 //
     30 // To work around all this, we're going to generally use timeGetTime().  We
     31 // will only increase the system-wide timer if we're not running on battery
     32 // power.
     33 
     34 #include "base/time/time.h"
     35 
     36 #include <windows.foundation.h>
     37 #include <windows.h>
     38 
     39 #include <mmsystem.h>
     40 #include <stdint.h>
     41 
     42 #include <atomic>
     43 #include <ostream>
     44 
     45 #include "base/bit_cast.h"
     46 #include "base/check_op.h"
     47 #include "base/cpu.h"
     48 #include "base/notreached.h"
     49 #include "base/synchronization/lock.h"
     50 #include "base/threading/platform_thread.h"
     51 #include "base/time/time_override.h"
     52 #include "build/build_config.h"
     53 
     54 namespace base {
     55 
     56 namespace {
     57 
     58 // From MSDN, FILETIME "Contains a 64-bit value representing the number of
     59 // 100-nanosecond intervals since January 1, 1601 (UTC)."
     60 int64_t FileTimeToMicroseconds(const FILETIME& ft) {
     61  // Need to bit_cast to fix alignment, then divide by 10 to convert
     62  // 100-nanoseconds to microseconds. This only works on little-endian
     63  // machines.
     64  return bit_cast<int64_t, FILETIME>(ft) / 10;
     65 }
     66 
     67 bool CanConvertToFileTime(int64_t us) {
     68  return us >= 0 && us <= (std::numeric_limits<int64_t>::max() / 10);
     69 }
     70 
     71 FILETIME MicrosecondsToFileTime(int64_t us) {
     72  DCHECK(CanConvertToFileTime(us)) << "Out-of-range: Cannot convert " << us
     73                                   << " microseconds to FILETIME units.";
     74 
     75  // Multiply by 10 to convert microseconds to 100-nanoseconds. Bit_cast will
     76  // handle alignment problems. This only works on little-endian machines.
     77  return bit_cast<FILETIME, int64_t>(us * 10);
     78 }
     79 
     80 int64_t CurrentWallclockMicroseconds() {
     81  FILETIME ft;
     82  ::GetSystemTimeAsFileTime(&ft);
     83  return FileTimeToMicroseconds(ft);
     84 }
     85 
     86 // Time between resampling the un-granular clock for this API.
     87 constexpr TimeDelta kMaxTimeToAvoidDrift = Seconds(60);
     88 
     89 int64_t g_initial_time = 0;
     90 TimeTicks g_initial_ticks;
     91 
     92 void InitializeClock() {
     93  g_initial_ticks = subtle::TimeTicksNowIgnoringOverride();
     94  g_initial_time = CurrentWallclockMicroseconds();
     95 }
     96 
     97 // Track the last value passed to timeBeginPeriod so that we can cancel that
     98 // call by calling timeEndPeriod with the same value. A value of zero means that
     99 // the timer frequency is not currently raised.
    100 UINT g_last_interval_requested_ms = 0;
    101 // Track if kMinTimerIntervalHighResMs or kMinTimerIntervalLowResMs is active.
    102 // For most purposes this could also be named g_is_on_ac_power.
    103 bool g_high_res_timer_enabled = false;
    104 // How many times the high resolution timer has been called.
    105 uint32_t g_high_res_timer_count = 0;
    106 // Start time of the high resolution timer usage monitoring. This is needed
    107 // to calculate the usage as percentage of the total elapsed time.
    108 TimeTicks g_high_res_timer_usage_start;
    109 // The cumulative time the high resolution timer has been in use since
    110 // |g_high_res_timer_usage_start| moment.
    111 TimeDelta g_high_res_timer_usage;
    112 // Timestamp of the last activation change of the high resolution timer. This
    113 // is used to calculate the cumulative usage.
    114 TimeTicks g_high_res_timer_last_activation;
    115 // The lock to control access to the above set of variables.
    116 Lock* GetHighResLock() {
    117  static auto* lock = new Lock();
    118  return lock;
    119 }
    120 
    121 // The two values that ActivateHighResolutionTimer uses to set the systemwide
    122 // timer interrupt frequency on Windows. These control how precise timers are
    123 // but also have a big impact on battery life.
    124 
    125 // Used when a faster timer has been requested (g_high_res_timer_count > 0) and
    126 // the computer is running on AC power (plugged in) so that it's okay to go to
    127 // the highest frequency.
    128 constexpr UINT kMinTimerIntervalHighResMs = 1;
    129 
    130 // Used when a faster timer has been requested (g_high_res_timer_count > 0) and
    131 // the computer is running on DC power (battery) so that we don't want to raise
    132 // the timer frequency as much.
    133 constexpr UINT kMinTimerIntervalLowResMs = 8;
    134 
    135 // Calculate the desired timer interrupt interval. Note that zero means that the
    136 // system default should be used.
    137 UINT GetIntervalMs() {
    138  if (!g_high_res_timer_count)
    139    return 0;  // Use the default, typically 15.625
    140  if (g_high_res_timer_enabled)
    141    return kMinTimerIntervalHighResMs;
    142  return kMinTimerIntervalLowResMs;
    143 }
    144 
    145 // Compare the currently requested timer interrupt interval to the last interval
    146 // requested and update if necessary (by cancelling the old request and making a
    147 // new request). If there is no change then do nothing.
    148 void UpdateTimerIntervalLocked() {
    149  UINT new_interval = GetIntervalMs();
    150  if (new_interval == g_last_interval_requested_ms)
    151    return;
    152  if (g_last_interval_requested_ms) {
    153    // Record how long the timer interrupt frequency was raised.
    154    g_high_res_timer_usage += subtle::TimeTicksNowIgnoringOverride() -
    155                              g_high_res_timer_last_activation;
    156    // Reset the timer interrupt back to the default.
    157    timeEndPeriod(g_last_interval_requested_ms);
    158  }
    159  g_last_interval_requested_ms = new_interval;
    160  if (g_last_interval_requested_ms) {
    161    // Record when the timer interrupt was raised.
    162    g_high_res_timer_last_activation = subtle::TimeTicksNowIgnoringOverride();
    163    timeBeginPeriod(g_last_interval_requested_ms);
    164  }
    165 }
    166 
    167 // Returns the current value of the performance counter.
    168 int64_t QPCNowRaw() {
    169  LARGE_INTEGER perf_counter_now = {};
    170  // According to the MSDN documentation for QueryPerformanceCounter(), this
    171  // will never fail on systems that run XP or later.
    172  // https://msdn.microsoft.com/library/windows/desktop/ms644904.aspx
    173  ::QueryPerformanceCounter(&perf_counter_now);
    174  return perf_counter_now.QuadPart;
    175 }
    176 
    177 bool SafeConvertToWord(int in, WORD* out) {
    178  CheckedNumeric<WORD> result = in;
    179  *out = result.ValueOrDefault(std::numeric_limits<WORD>::max());
    180  return result.IsValid();
    181 }
    182 
    183 }  // namespace
    184 
    185 // Time -----------------------------------------------------------------------
    186 
    187 namespace subtle {
    188 Time TimeNowIgnoringOverride() {
    189  if (g_initial_time == 0)
    190    InitializeClock();
    191 
    192  // We implement time using the high-resolution timers so that we can get
    193  // timeouts which are smaller than 10-15ms.  If we just used
    194  // CurrentWallclockMicroseconds(), we'd have the less-granular timer.
    195  //
    196  // To make this work, we initialize the clock (g_initial_time) and the
    197  // counter (initial_ctr).  To compute the initial time, we can check
    198  // the number of ticks that have elapsed, and compute the delta.
    199  //
    200  // To avoid any drift, we periodically resync the counters to the system
    201  // clock.
    202  while (true) {
    203    TimeTicks ticks = TimeTicksNowIgnoringOverride();
    204 
    205    // Calculate the time elapsed since we started our timer
    206    TimeDelta elapsed = ticks - g_initial_ticks;
    207 
    208    // Check if enough time has elapsed that we need to resync the clock.
    209    if (elapsed > kMaxTimeToAvoidDrift) {
    210      InitializeClock();
    211      continue;
    212    }
    213 
    214    return Time() + elapsed + Microseconds(g_initial_time);
    215  }
    216 }
    217 
    218 Time TimeNowFromSystemTimeIgnoringOverride() {
    219  // Force resync.
    220  InitializeClock();
    221  return Time() + Microseconds(g_initial_time);
    222 }
    223 }  // namespace subtle
    224 
    225 // static
    226 Time Time::FromFileTime(FILETIME ft) {
    227  if (bit_cast<int64_t, FILETIME>(ft) == 0)
    228    return Time();
    229  if (ft.dwHighDateTime == std::numeric_limits<DWORD>::max() &&
    230      ft.dwLowDateTime == std::numeric_limits<DWORD>::max())
    231    return Max();
    232  return Time(FileTimeToMicroseconds(ft));
    233 }
    234 
    235 FILETIME Time::ToFileTime() const {
    236  if (is_null())
    237    return bit_cast<FILETIME, int64_t>(0);
    238  if (is_max()) {
    239    FILETIME result;
    240    result.dwHighDateTime = std::numeric_limits<DWORD>::max();
    241    result.dwLowDateTime = std::numeric_limits<DWORD>::max();
    242    return result;
    243  }
    244  return MicrosecondsToFileTime(us_);
    245 }
    246 
    247 // static
    248 // Enable raising of the system-global timer interrupt frequency to 1 kHz (when
    249 // enable is true, which happens when on AC power) or some lower frequency when
    250 // on battery power (when enable is false). If the g_high_res_timer_enabled
    251 // setting hasn't actually changed or if if there are no outstanding requests
    252 // (if g_high_res_timer_count is zero) then do nothing.
    253 // TL;DR - call this when going from AC to DC power or vice-versa.
    254 void Time::EnableHighResolutionTimer(bool enable) {
    255  AutoLock lock(*GetHighResLock());
    256  g_high_res_timer_enabled = enable;
    257  UpdateTimerIntervalLocked();
    258 }
    259 
    260 // static
    261 // Request that the system-global Windows timer interrupt frequency be raised.
    262 // How high the frequency is raised depends on the system's power state and
    263 // possibly other options.
    264 // TL;DR - call this at the beginning and end of a time period where you want
    265 // higher frequency timer interrupts. Each call with activating=true must be
    266 // paired with a subsequent activating=false call.
    267 bool Time::ActivateHighResolutionTimer(bool activating) {
    268  // We only do work on the transition from zero to one or one to zero so we
    269  // can easily undo the effect (if necessary) when EnableHighResolutionTimer is
    270  // called.
    271  const uint32_t max = std::numeric_limits<uint32_t>::max();
    272 
    273  AutoLock lock(*GetHighResLock());
    274  if (activating) {
    275    DCHECK_NE(g_high_res_timer_count, max);
    276    ++g_high_res_timer_count;
    277  } else {
    278    DCHECK_NE(g_high_res_timer_count, 0u);
    279    --g_high_res_timer_count;
    280  }
    281  UpdateTimerIntervalLocked();
    282  return true;
    283 }
    284 
    285 // static
    286 // See if the timer interrupt interval has been set to the lowest value.
    287 bool Time::IsHighResolutionTimerInUse() {
    288  AutoLock lock(*GetHighResLock());
    289  return g_last_interval_requested_ms == kMinTimerIntervalHighResMs;
    290 }
    291 
    292 // static
    293 void Time::ResetHighResolutionTimerUsage() {
    294  AutoLock lock(*GetHighResLock());
    295  g_high_res_timer_usage = TimeDelta();
    296  g_high_res_timer_usage_start = subtle::TimeTicksNowIgnoringOverride();
    297  if (g_high_res_timer_count > 0)
    298    g_high_res_timer_last_activation = g_high_res_timer_usage_start;
    299 }
    300 
    301 // static
    302 double Time::GetHighResolutionTimerUsage() {
    303  AutoLock lock(*GetHighResLock());
    304  TimeTicks now = subtle::TimeTicksNowIgnoringOverride();
    305  TimeDelta elapsed_time = now - g_high_res_timer_usage_start;
    306  if (elapsed_time.is_zero()) {
    307    // This is unexpected but possible if TimeTicks resolution is low and
    308    // GetHighResolutionTimerUsage() is called promptly after
    309    // ResetHighResolutionTimerUsage().
    310    return 0.0;
    311  }
    312  TimeDelta used_time = g_high_res_timer_usage;
    313  if (g_high_res_timer_count > 0) {
    314    // If currently activated add the remainder of time since the last
    315    // activation.
    316    used_time += now - g_high_res_timer_last_activation;
    317  }
    318  return used_time / elapsed_time * 100;
    319 }
    320 
    321 // static
    322 bool Time::FromExploded(bool is_local, const Exploded& exploded, Time* time) {
    323  // Create the system struct representing our exploded time. It will either be
    324  // in local time or UTC.If casting from int to WORD results in overflow,
    325  // fail and return Time(0).
    326  SYSTEMTIME st;
    327  if (!SafeConvertToWord(exploded.year, &st.wYear) ||
    328      !SafeConvertToWord(exploded.month, &st.wMonth) ||
    329      !SafeConvertToWord(exploded.day_of_week, &st.wDayOfWeek) ||
    330      !SafeConvertToWord(exploded.day_of_month, &st.wDay) ||
    331      !SafeConvertToWord(exploded.hour, &st.wHour) ||
    332      !SafeConvertToWord(exploded.minute, &st.wMinute) ||
    333      !SafeConvertToWord(exploded.second, &st.wSecond) ||
    334      !SafeConvertToWord(exploded.millisecond, &st.wMilliseconds)) {
    335    *time = Time(0);
    336    return false;
    337  }
    338 
    339  FILETIME ft;
    340  bool success = true;
    341  // Ensure that it's in UTC.
    342  if (is_local) {
    343    SYSTEMTIME utc_st;
    344    success = TzSpecificLocalTimeToSystemTime(nullptr, &st, &utc_st) &&
    345              SystemTimeToFileTime(&utc_st, &ft);
    346  } else {
    347    success = !!SystemTimeToFileTime(&st, &ft);
    348  }
    349 
    350  *time = Time(success ? FileTimeToMicroseconds(ft) : 0);
    351  return success;
    352 }
    353 
    354 void Time::Explode(bool is_local, Exploded* exploded) const {
    355  if (!CanConvertToFileTime(us_)) {
    356    // We are not able to convert it to FILETIME.
    357    ZeroMemory(exploded, sizeof(*exploded));
    358    return;
    359  }
    360 
    361  const FILETIME utc_ft = MicrosecondsToFileTime(us_);
    362 
    363  // FILETIME in local time if necessary.
    364  bool success = true;
    365  // FILETIME in SYSTEMTIME (exploded).
    366  SYSTEMTIME st = {0};
    367  if (is_local) {
    368    SYSTEMTIME utc_st;
    369    // We don't use FileTimeToLocalFileTime here, since it uses the current
    370    // settings for the time zone and daylight saving time. Therefore, if it is
    371    // daylight saving time, it will take daylight saving time into account,
    372    // even if the time you are converting is in standard time.
    373    success = FileTimeToSystemTime(&utc_ft, &utc_st) &&
    374              SystemTimeToTzSpecificLocalTime(nullptr, &utc_st, &st);
    375  } else {
    376    success = !!FileTimeToSystemTime(&utc_ft, &st);
    377  }
    378 
    379  if (!success) {
    380    ZeroMemory(exploded, sizeof(*exploded));
    381    return;
    382  }
    383 
    384  exploded->year = st.wYear;
    385  exploded->month = st.wMonth;
    386  exploded->day_of_week = st.wDayOfWeek;
    387  exploded->day_of_month = st.wDay;
    388  exploded->hour = st.wHour;
    389  exploded->minute = st.wMinute;
    390  exploded->second = st.wSecond;
    391  exploded->millisecond = st.wMilliseconds;
    392 }
    393 
    394 // TimeTicks ------------------------------------------------------------------
    395 
    396 namespace {
    397 
    398 // We define a wrapper to adapt between the __stdcall and __cdecl call of the
    399 // mock function, and to avoid a static constructor.  Assigning an import to a
    400 // function pointer directly would require setup code to fetch from the IAT.
    401 DWORD timeGetTimeWrapper() {
    402  return timeGetTime();
    403 }
    404 
    405 DWORD (*g_tick_function)(void) = &timeGetTimeWrapper;
    406 
    407 // A structure holding the most significant bits of "last seen" and a
    408 // "rollover" counter.
    409 union LastTimeAndRolloversState {
    410  // The state as a single 32-bit opaque value.
    411  std::atomic<int32_t> as_opaque_32{0};
    412 
    413  // The state as usable values.
    414  struct {
    415    // The top 8-bits of the "last" time. This is enough to check for rollovers
    416    // and the small bit-size means fewer CompareAndSwap operations to store
    417    // changes in state, which in turn makes for fewer retries.
    418    uint8_t last_8;
    419    // A count of the number of detected rollovers. Using this as bits 47-32
    420    // of the upper half of a 64-bit value results in a 48-bit tick counter.
    421    // This extends the total rollover period from about 49 days to about 8800
    422    // years while still allowing it to be stored with last_8 in a single
    423    // 32-bit value.
    424    uint16_t rollovers;
    425  } as_values;
    426 };
    427 std::atomic<int32_t> g_last_time_and_rollovers = 0;
    428 static_assert(
    429    sizeof(LastTimeAndRolloversState) <= sizeof(g_last_time_and_rollovers),
    430    "LastTimeAndRolloversState does not fit in a single atomic word");
    431 
    432 // We use timeGetTime() to implement TimeTicks::Now().  This can be problematic
    433 // because it returns the number of milliseconds since Windows has started,
    434 // which will roll over the 32-bit value every ~49 days.  We try to track
    435 // rollover ourselves, which works if TimeTicks::Now() is called at least every
    436 // 48.8 days (not 49 days because only changes in the top 8 bits get noticed).
    437 TimeTicks RolloverProtectedNow() {
    438  LastTimeAndRolloversState state;
    439  DWORD now;  // DWORD is always unsigned 32 bits.
    440 
    441  while (true) {
    442    // Fetch the "now" and "last" tick values, updating "last" with "now" and
    443    // incrementing the "rollovers" counter if the tick-value has wrapped back
    444    // around. Atomic operations ensure that both "last" and "rollovers" are
    445    // always updated together.
    446    int32_t original =
    447        g_last_time_and_rollovers.load(std::memory_order_acquire);
    448    state.as_opaque_32 = original;
    449    now = g_tick_function();
    450    uint8_t now_8 = static_cast<uint8_t>(now >> 24);
    451    if (now_8 < state.as_values.last_8)
    452      ++state.as_values.rollovers;
    453    state.as_values.last_8 = now_8;
    454 
    455    // If the state hasn't changed, exit the loop.
    456    if (state.as_opaque_32 == original)
    457      break;
    458 
    459    // Save the changed state. If the existing value is unchanged from the
    460    // original so that the operation is successful. Exit the loop.
    461    bool success = g_last_time_and_rollovers.compare_exchange_strong(
    462        original, state.as_opaque_32, std::memory_order_release);
    463    if (success)
    464      break;
    465 
    466    // Another thread has done something in between so retry from the top.
    467  }
    468 
    469  return TimeTicks() +
    470         Milliseconds(now +
    471                      (static_cast<uint64_t>(state.as_values.rollovers) << 32));
    472 }
    473 
    474 // Discussion of tick counter options on Windows:
    475 //
    476 // (1) CPU cycle counter. (Retrieved via RDTSC)
    477 // The CPU counter provides the highest resolution time stamp and is the least
    478 // expensive to retrieve. However, on older CPUs, two issues can affect its
    479 // reliability: First it is maintained per processor and not synchronized
    480 // between processors. Also, the counters will change frequency due to thermal
    481 // and power changes, and stop in some states.
    482 //
    483 // (2) QueryPerformanceCounter (QPC). The QPC counter provides a high-
    484 // resolution (<1 microsecond) time stamp. On most hardware running today, it
    485 // auto-detects and uses the constant-rate RDTSC counter to provide extremely
    486 // efficient and reliable time stamps.
    487 //
    488 // On older CPUs where RDTSC is unreliable, it falls back to using more
    489 // expensive (20X to 40X more costly) alternate clocks, such as HPET or the ACPI
    490 // PM timer, and can involve system calls; and all this is up to the HAL (with
    491 // some help from ACPI). According to
    492 // http://blogs.msdn.com/oldnewthing/archive/2005/09/02/459952.aspx, in the
    493 // worst case, it gets the counter from the rollover interrupt on the
    494 // programmable interrupt timer. In best cases, the HAL may conclude that the
    495 // RDTSC counter runs at a constant frequency, then it uses that instead. On
    496 // multiprocessor machines, it will try to verify the values returned from
    497 // RDTSC on each processor are consistent with each other, and apply a handful
    498 // of workarounds for known buggy hardware. In other words, QPC is supposed to
    499 // give consistent results on a multiprocessor computer, but for older CPUs it
    500 // can be unreliable due bugs in BIOS or HAL.
    501 //
    502 // (3) System time. The system time provides a low-resolution (from ~1 to ~15.6
    503 // milliseconds) time stamp but is comparatively less expensive to retrieve and
    504 // more reliable. Time::EnableHighResolutionTimer() and
    505 // Time::ActivateHighResolutionTimer() can be called to alter the resolution of
    506 // this timer; and also other Windows applications can alter it, affecting this
    507 // one.
    508 
    509 TimeTicks InitialNowFunction();
    510 
    511 // See "threading notes" in InitializeNowFunctionPointer() for details on how
    512 // concurrent reads/writes to these globals has been made safe.
    513 std::atomic<TimeTicksNowFunction> g_time_ticks_now_ignoring_override_function{
    514    &InitialNowFunction};
    515 int64_t g_qpc_ticks_per_second = 0;
    516 
    517 TimeDelta QPCValueToTimeDelta(LONGLONG qpc_value) {
    518  // Ensure that the assignment to |g_qpc_ticks_per_second|, made in
    519  // InitializeNowFunctionPointer(), has happened by this point.
    520  std::atomic_thread_fence(std::memory_order_acquire);
    521 
    522  DCHECK_GT(g_qpc_ticks_per_second, 0);
    523 
    524  // If the QPC Value is below the overflow threshold, we proceed with
    525  // simple multiply and divide.
    526  if (qpc_value < Time::kQPCOverflowThreshold) {
    527    return Microseconds(qpc_value * Time::kMicrosecondsPerSecond /
    528                        g_qpc_ticks_per_second);
    529  }
    530  // Otherwise, calculate microseconds in a round about manner to avoid
    531  // overflow and precision issues.
    532  int64_t whole_seconds = qpc_value / g_qpc_ticks_per_second;
    533  int64_t leftover_ticks = qpc_value - (whole_seconds * g_qpc_ticks_per_second);
    534  return Microseconds((whole_seconds * Time::kMicrosecondsPerSecond) +
    535                      ((leftover_ticks * Time::kMicrosecondsPerSecond) /
    536                       g_qpc_ticks_per_second));
    537 }
    538 
    539 TimeTicks QPCNow() {
    540  return TimeTicks() + QPCValueToTimeDelta(QPCNowRaw());
    541 }
    542 
    543 void InitializeNowFunctionPointer() {
    544  LARGE_INTEGER ticks_per_sec = {};
    545  if (!QueryPerformanceFrequency(&ticks_per_sec))
    546    ticks_per_sec.QuadPart = 0;
    547 
    548  // If Windows cannot provide a QPC implementation, TimeTicks::Now() must use
    549  // the low-resolution clock.
    550  //
    551  // If the QPC implementation is expensive and/or unreliable, TimeTicks::Now()
    552  // will still use the low-resolution clock. A CPU lacking a non-stop time
    553  // counter will cause Windows to provide an alternate QPC implementation that
    554  // works, but is expensive to use.
    555  //
    556  // Otherwise, Now uses the high-resolution QPC clock. As of 21 August 2015,
    557  // ~72% of users fall within this category.
    558  CPU cpu;
    559  const TimeTicksNowFunction now_function =
    560      (ticks_per_sec.QuadPart <= 0 || !cpu.has_non_stop_time_stamp_counter())
    561          ? &RolloverProtectedNow
    562          : &QPCNow;
    563 
    564  // Threading note 1: In an unlikely race condition, it's possible for two or
    565  // more threads to enter InitializeNowFunctionPointer() in parallel. This is
    566  // not a problem since all threads end up writing out the same values
    567  // to the global variables, and those variable being atomic are safe to read
    568  // from other threads.
    569  //
    570  // Threading note 2: A release fence is placed here to ensure, from the
    571  // perspective of other threads using the function pointers, that the
    572  // assignment to |g_qpc_ticks_per_second| happens before the function pointers
    573  // are changed.
    574  g_qpc_ticks_per_second = ticks_per_sec.QuadPart;
    575  std::atomic_thread_fence(std::memory_order_release);
    576  // Also set g_time_ticks_now_function to avoid the additional indirection via
    577  // TimeTicksNowIgnoringOverride() for future calls to TimeTicks::Now(), only
    578  // if it wasn't already overridden to a different value. memory_order_relaxed
    579  // is sufficient since an explicit fence was inserted above.
    580  base::TimeTicksNowFunction initial_time_ticks_now_function =
    581      &subtle::TimeTicksNowIgnoringOverride;
    582  internal::g_time_ticks_now_function.compare_exchange_strong(
    583      initial_time_ticks_now_function, now_function, std::memory_order_relaxed);
    584  g_time_ticks_now_ignoring_override_function.store(now_function,
    585                                                    std::memory_order_relaxed);
    586 }
    587 
    588 TimeTicks InitialNowFunction() {
    589  InitializeNowFunctionPointer();
    590  return g_time_ticks_now_ignoring_override_function.load(
    591      std::memory_order_relaxed)();
    592 }
    593 
    594 }  // namespace
    595 
    596 // static
    597 TimeTicks::TickFunctionType TimeTicks::SetMockTickFunction(
    598    TickFunctionType ticker) {
    599  TickFunctionType old = g_tick_function;
    600  g_tick_function = ticker;
    601  g_last_time_and_rollovers.store(0, std::memory_order_relaxed);
    602  return old;
    603 }
    604 
    605 namespace subtle {
    606 TimeTicks TimeTicksNowIgnoringOverride() {
    607  return g_time_ticks_now_ignoring_override_function.load(
    608      std::memory_order_relaxed)();
    609 }
    610 }  // namespace subtle
    611 
    612 // static
    613 bool TimeTicks::IsHighResolution() {
    614  if (g_time_ticks_now_ignoring_override_function == &InitialNowFunction)
    615    InitializeNowFunctionPointer();
    616  return g_time_ticks_now_ignoring_override_function == &QPCNow;
    617 }
    618 
    619 // static
    620 bool TimeTicks::IsConsistentAcrossProcesses() {
    621  // According to Windows documentation [1] QPC is consistent post-Windows
    622  // Vista. So if we are using QPC then we are consistent which is the same as
    623  // being high resolution.
    624  //
    625  // [1] https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
    626  //
    627  // "In general, the performance counter results are consistent across all
    628  // processors in multi-core and multi-processor systems, even when measured on
    629  // different threads or processes. Here are some exceptions to this rule:
    630  // - Pre-Windows Vista operating systems that run on certain processors might
    631  // violate this consistency because of one of these reasons:
    632  //     1. The hardware processors have a non-invariant TSC and the BIOS
    633  //     doesn't indicate this condition correctly.
    634  //     2. The TSC synchronization algorithm that was used wasn't suitable for
    635  //     systems with large numbers of processors."
    636  return IsHighResolution();
    637 }
    638 
    639 // static
    640 TimeTicks::Clock TimeTicks::GetClock() {
    641  return IsHighResolution() ? Clock::WIN_QPC
    642                            : Clock::WIN_ROLLOVER_PROTECTED_TIME_GET_TIME;
    643 }
    644 
    645 // LiveTicks ------------------------------------------------------------------
    646 
    647 #if !defined(MOZ_SANDBOX)
    648 namespace subtle {
    649 LiveTicks LiveTicksNowIgnoringOverride() {
    650  ULONGLONG unbiased_interrupt_time;
    651  QueryUnbiasedInterruptTimePrecise(&unbiased_interrupt_time);
    652  // QueryUnbiasedInterruptTimePrecise gets the interrupt time in system time
    653  // units of 100 nanoseconds.
    654  return LiveTicks() + Nanoseconds(unbiased_interrupt_time * 100);
    655 }
    656 }  // namespace subtle
    657 #endif
    658 
    659 // ThreadTicks ----------------------------------------------------------------
    660 
    661 namespace subtle {
    662 ThreadTicks ThreadTicksNowIgnoringOverride() {
    663  return ThreadTicks::GetForThread(PlatformThread::CurrentHandle());
    664 }
    665 }  // namespace subtle
    666 
    667 // static
    668 ThreadTicks ThreadTicks::GetForThread(
    669    const PlatformThreadHandle& thread_handle) {
    670  DCHECK(IsSupported());
    671 
    672 #if defined(ARCH_CPU_ARM64)
    673  // QueryThreadCycleTime versus TSCTicksPerSecond doesn't have much relation to
    674  // actual elapsed time on Windows on Arm, because QueryThreadCycleTime is
    675  // backed by the actual number of CPU cycles executed, rather than a
    676  // constant-rate timer like Intel. To work around this, use GetThreadTimes
    677  // (which isn't as accurate but is meaningful as a measure of elapsed
    678  // per-thread time).
    679  FILETIME creation_time, exit_time, kernel_time, user_time;
    680  ::GetThreadTimes(thread_handle.platform_handle(), &creation_time, &exit_time,
    681                   &kernel_time, &user_time);
    682 
    683  const int64_t us = FileTimeToMicroseconds(user_time);
    684 #else
    685  // Get the number of TSC ticks used by the current thread.
    686  ULONG64 thread_cycle_time = 0;
    687  ::QueryThreadCycleTime(thread_handle.platform_handle(), &thread_cycle_time);
    688 
    689  // Get the frequency of the TSC.
    690  const double tsc_ticks_per_second = time_internal::TSCTicksPerSecond();
    691  if (tsc_ticks_per_second == 0)
    692    return ThreadTicks();
    693 
    694  // Return the CPU time of the current thread.
    695  const double thread_time_seconds = thread_cycle_time / tsc_ticks_per_second;
    696  const int64_t us =
    697      static_cast<int64_t>(thread_time_seconds * Time::kMicrosecondsPerSecond);
    698 #endif
    699 
    700  return ThreadTicks(us);
    701 }
    702 
    703 // static
    704 bool ThreadTicks::IsSupportedWin() {
    705 #if defined(ARCH_CPU_ARM64)
    706  // The Arm implementation does not use QueryThreadCycleTime and therefore does
    707  // not care about the time stamp counter.
    708  return true;
    709 #else
    710  return time_internal::HasConstantRateTSC();
    711 #endif
    712 }
    713 
    714 // static
    715 void ThreadTicks::WaitUntilInitializedWin() {
    716 #if !defined(ARCH_CPU_ARM64)
    717  while (time_internal::TSCTicksPerSecond() == 0)
    718    ::Sleep(10);
    719 #endif
    720 }
    721 
    722 // static
    723 TimeTicks TimeTicks::FromQPCValue(LONGLONG qpc_value) {
    724  return TimeTicks() + QPCValueToTimeDelta(qpc_value);
    725 }
    726 
    727 // TimeDelta ------------------------------------------------------------------
    728 
    729 // static
    730 TimeDelta TimeDelta::FromQPCValue(LONGLONG qpc_value) {
    731  return QPCValueToTimeDelta(qpc_value);
    732 }
    733 
    734 // static
    735 TimeDelta TimeDelta::FromFileTime(FILETIME ft) {
    736  return Microseconds(FileTimeToMicroseconds(ft));
    737 }
    738 
    739 // static
    740 TimeDelta TimeDelta::FromWinrtDateTime(ABI::Windows::Foundation::DateTime dt) {
    741  // UniversalTime is 100 ns intervals since January 1, 1601 (UTC)
    742  return Microseconds(dt.UniversalTime / 10);
    743 }
    744 
    745 ABI::Windows::Foundation::DateTime TimeDelta::ToWinrtDateTime() const {
    746  ABI::Windows::Foundation::DateTime date_time;
    747  date_time.UniversalTime = InMicroseconds() * 10;
    748  return date_time;
    749 }
    750 
    751 // static
    752 TimeDelta TimeDelta::FromWinrtTimeSpan(ABI::Windows::Foundation::TimeSpan ts) {
    753  // Duration is 100 ns intervals
    754  return Microseconds(ts.Duration / 10);
    755 }
    756 
    757 ABI::Windows::Foundation::TimeSpan TimeDelta::ToWinrtTimeSpan() const {
    758  ABI::Windows::Foundation::TimeSpan time_span;
    759  time_span.Duration = InMicroseconds() * 10;
    760  return time_span;
    761 }
    762 
    763 #if !defined(ARCH_CPU_ARM64)
    764 namespace time_internal {
    765 
    766 bool HasConstantRateTSC() {
    767  static bool is_supported = CPU().has_non_stop_time_stamp_counter();
    768  return is_supported;
    769 }
    770 
    771 double TSCTicksPerSecond() {
    772  DCHECK(HasConstantRateTSC());
    773  // The value returned by QueryPerformanceFrequency() cannot be used as the TSC
    774  // frequency, because there is no guarantee that the TSC frequency is equal to
    775  // the performance counter frequency.
    776  // The TSC frequency is cached in a static variable because it takes some time
    777  // to compute it.
    778  static double tsc_ticks_per_second = 0;
    779  if (tsc_ticks_per_second != 0)
    780    return tsc_ticks_per_second;
    781 
    782  // Increase the thread priority to reduces the chances of having a context
    783  // switch during a reading of the TSC and the performance counter.
    784  const int previous_priority = ::GetThreadPriority(::GetCurrentThread());
    785  ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
    786 
    787  // The first time that this function is called, make an initial reading of the
    788  // TSC and the performance counter.
    789 
    790  static const uint64_t tsc_initial = __rdtsc();
    791  static const int64_t perf_counter_initial = QPCNowRaw();
    792 
    793  // Make a another reading of the TSC and the performance counter every time
    794  // that this function is called.
    795  const uint64_t tsc_now = __rdtsc();
    796  const int64_t perf_counter_now = QPCNowRaw();
    797 
    798  // Reset the thread priority.
    799  ::SetThreadPriority(::GetCurrentThread(), previous_priority);
    800 
    801  // Make sure that at least 50 ms elapsed between the 2 readings. The first
    802  // time that this function is called, we don't expect this to be the case.
    803  // Note: The longer the elapsed time between the 2 readings is, the more
    804  //   accurate the computed TSC frequency will be. The 50 ms value was
    805  //   chosen because local benchmarks show that it allows us to get a
    806  //   stddev of less than 1 tick/us between multiple runs.
    807  // Note: According to the MSDN documentation for QueryPerformanceFrequency(),
    808  //   this will never fail on systems that run XP or later.
    809  //   https://msdn.microsoft.com/library/windows/desktop/ms644905.aspx
    810  LARGE_INTEGER perf_counter_frequency = {};
    811  ::QueryPerformanceFrequency(&perf_counter_frequency);
    812  DCHECK_GE(perf_counter_now, perf_counter_initial);
    813  const int64_t perf_counter_ticks = perf_counter_now - perf_counter_initial;
    814  const double elapsed_time_seconds =
    815      perf_counter_ticks / static_cast<double>(perf_counter_frequency.QuadPart);
    816 
    817  constexpr double kMinimumEvaluationPeriodSeconds = 0.05;
    818  if (elapsed_time_seconds < kMinimumEvaluationPeriodSeconds)
    819    return 0;
    820 
    821  // Compute the frequency of the TSC.
    822  DCHECK_GE(tsc_now, tsc_initial);
    823  const uint64_t tsc_ticks = tsc_now - tsc_initial;
    824  tsc_ticks_per_second = tsc_ticks / elapsed_time_seconds;
    825 
    826  return tsc_ticks_per_second;
    827 }
    828 
    829 }  // namespace time_internal
    830 #endif  // defined(ARCH_CPU_ARM64)
    831 
    832 }  // namespace base