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