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