roll skia to 4276
[chromium-blink-merge.git] / base / time_win.cc
blob71c914da29dabe75003d9e83172269d3ac72a717
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.
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
11 // The default windows timer, GetSystemTimeAsFileTime is not very precise.
12 // It is only good to ~15.5ms.
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.
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
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. Using timeBeginPeriod(1) is a requirement in order to make our
33 // message loop waits have the same resolution that our time measurements
34 // do. Otherwise, WaitForSingleObject(..., 1) will no less than 15ms when
35 // there is nothing else to waken the Wait.
37 #include "base/time.h"
39 #pragma comment(lib, "winmm.lib")
40 #include <windows.h>
41 #include <mmsystem.h>
43 #include "base/basictypes.h"
44 #include "base/logging.h"
45 #include "base/cpu.h"
46 #include "base/memory/singleton.h"
47 #include "base/synchronization/lock.h"
49 using base::Time;
50 using base::TimeDelta;
51 using base::TimeTicks;
53 namespace {
55 // From MSDN, FILETIME "Contains a 64-bit value representing the number of
56 // 100-nanosecond intervals since January 1, 1601 (UTC)."
57 int64 FileTimeToMicroseconds(const FILETIME& ft) {
58 // Need to bit_cast to fix alignment, then divide by 10 to convert
59 // 100-nanoseconds to milliseconds. This only works on little-endian
60 // machines.
61 return bit_cast<int64, FILETIME>(ft) / 10;
64 void MicrosecondsToFileTime(int64 us, FILETIME* ft) {
65 DCHECK_GE(us, 0LL) << "Time is less than 0, negative values are not "
66 "representable in FILETIME";
68 // Multiply by 10 to convert milliseconds to 100-nanoseconds. Bit_cast will
69 // handle alignment problems. This only works on little-endian machines.
70 *ft = bit_cast<FILETIME, int64>(us * 10);
73 int64 CurrentWallclockMicroseconds() {
74 FILETIME ft;
75 ::GetSystemTimeAsFileTime(&ft);
76 return FileTimeToMicroseconds(ft);
79 // Time between resampling the un-granular clock for this API. 60 seconds.
80 const int kMaxMillisecondsToAvoidDrift = 60 * Time::kMillisecondsPerSecond;
82 int64 initial_time = 0;
83 TimeTicks initial_ticks;
85 void InitializeClock() {
86 initial_ticks = TimeTicks::Now();
87 initial_time = CurrentWallclockMicroseconds();
90 } // namespace
92 // Time -----------------------------------------------------------------------
94 // The internal representation of Time uses FILETIME, whose epoch is 1601-01-01
95 // 00:00:00 UTC. ((1970-1601)*365+89)*24*60*60*1000*1000, where 89 is the
96 // number of leap year days between 1601 and 1970: (1970-1601)/4 excluding
97 // 1700, 1800, and 1900.
98 // static
99 const int64 Time::kTimeTToMicrosecondsOffset = GG_INT64_C(11644473600000000);
101 bool Time::high_resolution_timer_enabled_ = false;
102 int Time::high_resolution_timer_activated_ = 0;
104 // static
105 Time Time::Now() {
106 if (initial_time == 0)
107 InitializeClock();
109 // We implement time using the high-resolution timers so that we can get
110 // timeouts which are smaller than 10-15ms. If we just used
111 // CurrentWallclockMicroseconds(), we'd have the less-granular timer.
113 // To make this work, we initialize the clock (initial_time) and the
114 // counter (initial_ctr). To compute the initial time, we can check
115 // the number of ticks that have elapsed, and compute the delta.
117 // To avoid any drift, we periodically resync the counters to the system
118 // clock.
119 while (true) {
120 TimeTicks ticks = TimeTicks::Now();
122 // Calculate the time elapsed since we started our timer
123 TimeDelta elapsed = ticks - initial_ticks;
125 // Check if enough time has elapsed that we need to resync the clock.
126 if (elapsed.InMilliseconds() > kMaxMillisecondsToAvoidDrift) {
127 InitializeClock();
128 continue;
131 return Time(elapsed + Time(initial_time));
135 // static
136 Time Time::NowFromSystemTime() {
137 // Force resync.
138 InitializeClock();
139 return Time(initial_time);
142 // static
143 Time Time::FromFileTime(FILETIME ft) {
144 return Time(FileTimeToMicroseconds(ft));
147 FILETIME Time::ToFileTime() const {
148 FILETIME utc_ft;
149 MicrosecondsToFileTime(us_, &utc_ft);
150 return utc_ft;
153 // static
154 void Time::EnableHighResolutionTimer(bool enable) {
155 // Test for single-threaded access.
156 static PlatformThreadId my_thread = PlatformThread::CurrentId();
157 DCHECK(PlatformThread::CurrentId() == my_thread);
159 if (high_resolution_timer_enabled_ == enable)
160 return;
162 high_resolution_timer_enabled_ = enable;
165 // static
166 bool Time::ActivateHighResolutionTimer(bool activating) {
167 if (!high_resolution_timer_enabled_ && activating)
168 return false;
170 // Using anything other than 1ms makes timers granular
171 // to that interval.
172 const int kMinTimerIntervalMs = 1;
173 MMRESULT result;
174 if (activating) {
175 result = timeBeginPeriod(kMinTimerIntervalMs);
176 high_resolution_timer_activated_++;
177 } else {
178 result = timeEndPeriod(kMinTimerIntervalMs);
179 high_resolution_timer_activated_--;
181 return result == TIMERR_NOERROR;
184 // static
185 bool Time::IsHighResolutionTimerInUse() {
186 // Note: we should track the high_resolution_timer_activated_ value
187 // under a lock if we want it to be accurate in a system with multiple
188 // message loops. We don't do that - because we don't want to take the
189 // expense of a lock for this. We *only* track this value so that unit
190 // tests can see if the high resolution timer is on or off.
191 return high_resolution_timer_enabled_ &&
192 high_resolution_timer_activated_ > 0;
195 // static
196 Time Time::FromExploded(bool is_local, const Exploded& exploded) {
197 // Create the system struct representing our exploded time. It will either be
198 // in local time or UTC.
199 SYSTEMTIME st;
200 st.wYear = exploded.year;
201 st.wMonth = exploded.month;
202 st.wDayOfWeek = exploded.day_of_week;
203 st.wDay = exploded.day_of_month;
204 st.wHour = exploded.hour;
205 st.wMinute = exploded.minute;
206 st.wSecond = exploded.second;
207 st.wMilliseconds = exploded.millisecond;
209 FILETIME ft;
210 bool success = true;
211 // Ensure that it's in UTC.
212 if (is_local) {
213 SYSTEMTIME utc_st;
214 success = TzSpecificLocalTimeToSystemTime(NULL, &st, &utc_st) &&
215 SystemTimeToFileTime(&utc_st, &ft);
216 } else {
217 success = !!SystemTimeToFileTime(&st, &ft);
220 if (!success) {
221 NOTREACHED() << "Unable to convert time";
222 return Time(0);
224 return Time(FileTimeToMicroseconds(ft));
227 void Time::Explode(bool is_local, Exploded* exploded) const {
228 if (us_ < 0LL) {
229 // We are not able to convert it to FILETIME.
230 ZeroMemory(exploded, sizeof(*exploded));
231 return;
234 // FILETIME in UTC.
235 FILETIME utc_ft;
236 MicrosecondsToFileTime(us_, &utc_ft);
238 // FILETIME in local time if necessary.
239 bool success = true;
240 // FILETIME in SYSTEMTIME (exploded).
241 SYSTEMTIME st;
242 if (is_local) {
243 SYSTEMTIME utc_st;
244 // We don't use FileTimeToLocalFileTime here, since it uses the current
245 // settings for the time zone and daylight saving time. Therefore, if it is
246 // daylight saving time, it will take daylight saving time into account,
247 // even if the time you are converting is in standard time.
248 success = FileTimeToSystemTime(&utc_ft, &utc_st) &&
249 SystemTimeToTzSpecificLocalTime(NULL, &utc_st, &st);
250 } else {
251 success = !!FileTimeToSystemTime(&utc_ft, &st);
254 if (!success) {
255 NOTREACHED() << "Unable to convert time, don't know why";
256 ZeroMemory(exploded, sizeof(*exploded));
257 return;
260 exploded->year = st.wYear;
261 exploded->month = st.wMonth;
262 exploded->day_of_week = st.wDayOfWeek;
263 exploded->day_of_month = st.wDay;
264 exploded->hour = st.wHour;
265 exploded->minute = st.wMinute;
266 exploded->second = st.wSecond;
267 exploded->millisecond = st.wMilliseconds;
270 // TimeTicks ------------------------------------------------------------------
271 namespace {
273 // We define a wrapper to adapt between the __stdcall and __cdecl call of the
274 // mock function, and to avoid a static constructor. Assigning an import to a
275 // function pointer directly would require setup code to fetch from the IAT.
276 DWORD timeGetTimeWrapper() {
277 return timeGetTime();
280 DWORD (*tick_function)(void) = &timeGetTimeWrapper;
282 // Accumulation of time lost due to rollover (in milliseconds).
283 int64 rollover_ms = 0;
285 // The last timeGetTime value we saw, to detect rollover.
286 DWORD last_seen_now = 0;
288 // Lock protecting rollover_ms and last_seen_now.
289 // Note: this is a global object, and we usually avoid these. However, the time
290 // code is low-level, and we don't want to use Singletons here (it would be too
291 // easy to use a Singleton without even knowing it, and that may lead to many
292 // gotchas). Its impact on startup time should be negligible due to low-level
293 // nature of time code.
294 base::Lock rollover_lock;
296 // We use timeGetTime() to implement TimeTicks::Now(). This can be problematic
297 // because it returns the number of milliseconds since Windows has started,
298 // which will roll over the 32-bit value every ~49 days. We try to track
299 // rollover ourselves, which works if TimeTicks::Now() is called at least every
300 // 49 days.
301 TimeDelta RolloverProtectedNow() {
302 base::AutoLock locked(rollover_lock);
303 // We should hold the lock while calling tick_function to make sure that
304 // we keep last_seen_now stay correctly in sync.
305 DWORD now = tick_function();
306 if (now < last_seen_now)
307 rollover_ms += 0x100000000I64; // ~49.7 days.
308 last_seen_now = now;
309 return TimeDelta::FromMilliseconds(now + rollover_ms);
312 // Overview of time counters:
313 // (1) CPU cycle counter. (Retrieved via RDTSC)
314 // The CPU counter provides the highest resolution time stamp and is the least
315 // expensive to retrieve. However, the CPU counter is unreliable and should not
316 // be used in production. Its biggest issue is that it is per processor and it
317 // is not synchronized between processors. Also, on some computers, the counters
318 // will change frequency due to thermal and power changes, and stop in some
319 // states.
321 // (2) QueryPerformanceCounter (QPC). The QPC counter provides a high-
322 // resolution (100 nanoseconds) time stamp but is comparatively more expensive
323 // to retrieve. What QueryPerformanceCounter actually does is up to the HAL.
324 // (with some help from ACPI).
325 // According to http://blogs.msdn.com/oldnewthing/archive/2005/09/02/459952.aspx
326 // in the worst case, it gets the counter from the rollover interrupt on the
327 // programmable interrupt timer. In best cases, the HAL may conclude that the
328 // RDTSC counter runs at a constant frequency, then it uses that instead. On
329 // multiprocessor machines, it will try to verify the values returned from
330 // RDTSC on each processor are consistent with each other, and apply a handful
331 // of workarounds for known buggy hardware. In other words, QPC is supposed to
332 // give consistent result on a multiprocessor computer, but it is unreliable in
333 // reality due to bugs in BIOS or HAL on some, especially old computers.
334 // With recent updates on HAL and newer BIOS, QPC is getting more reliable but
335 // it should be used with caution.
337 // (3) System time. The system time provides a low-resolution (typically 10ms
338 // to 55 milliseconds) time stamp but is comparatively less expensive to
339 // retrieve and more reliable.
340 class HighResNowSingleton {
341 public:
342 static HighResNowSingleton* GetInstance() {
343 return Singleton<HighResNowSingleton>::get();
346 bool IsUsingHighResClock() {
347 return ticks_per_microsecond_ != 0.0;
350 void DisableHighResClock() {
351 ticks_per_microsecond_ = 0.0;
354 TimeDelta Now() {
355 if (IsUsingHighResClock())
356 return TimeDelta::FromMicroseconds(UnreliableNow());
358 // Just fallback to the slower clock.
359 return RolloverProtectedNow();
362 int64 GetQPCDriftMicroseconds() {
363 if (!IsUsingHighResClock())
364 return 0;
366 // The static_cast<long> is needed as a hint to VS 2008 to tell it
367 // which version of abs() to use. Other compilers don't seem to
368 // need it, including VS 2010, but to keep code identical we use it
369 // everywhere.
370 // TODO(joi): Remove the hint if/when we no longer support VS 2008.
371 return abs(static_cast<long>((UnreliableNow() - ReliableNow()) - skew_));
374 private:
375 HighResNowSingleton()
376 : ticks_per_microsecond_(0.0),
377 skew_(0) {
378 InitializeClock();
380 // On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is
381 // unreliable. Fallback to low-res clock.
382 base::CPU cpu;
383 if (cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15)
384 DisableHighResClock();
387 // Synchronize the QPC clock with GetSystemTimeAsFileTime.
388 void InitializeClock() {
389 LARGE_INTEGER ticks_per_sec = {0};
390 if (!QueryPerformanceFrequency(&ticks_per_sec))
391 return; // Broken, we don't guarantee this function works.
392 ticks_per_microsecond_ = static_cast<float>(ticks_per_sec.QuadPart) /
393 static_cast<float>(Time::kMicrosecondsPerSecond);
395 skew_ = UnreliableNow() - ReliableNow();
398 // Get the number of microseconds since boot in an unreliable fashion.
399 int64 UnreliableNow() {
400 LARGE_INTEGER now;
401 QueryPerformanceCounter(&now);
402 return static_cast<int64>(now.QuadPart / ticks_per_microsecond_);
405 // Get the number of microseconds since boot in a reliable fashion.
406 int64 ReliableNow() {
407 return RolloverProtectedNow().InMicroseconds();
410 // Cached clock frequency -> microseconds. This assumes that the clock
411 // frequency is faster than one microsecond (which is 1MHz, should be OK).
412 float ticks_per_microsecond_; // 0 indicates QPF failed and we're broken.
413 int64 skew_; // Skew between lo-res and hi-res clocks (for debugging).
415 friend struct DefaultSingletonTraits<HighResNowSingleton>;
418 } // namespace
420 // static
421 TimeTicks::TickFunctionType TimeTicks::SetMockTickFunction(
422 TickFunctionType ticker) {
423 TickFunctionType old = tick_function;
424 tick_function = ticker;
425 return old;
428 // static
429 TimeTicks TimeTicks::Now() {
430 return TimeTicks() + RolloverProtectedNow();
433 // static
434 TimeTicks TimeTicks::HighResNow() {
435 return TimeTicks() + HighResNowSingleton::GetInstance()->Now();
438 // static
439 TimeTicks TimeTicks::NowFromSystemTraceTime() {
440 return HighResNow();
443 // static
444 int64 TimeTicks::GetQPCDriftMicroseconds() {
445 return HighResNowSingleton::GetInstance()->GetQPCDriftMicroseconds();
448 // static
449 bool TimeTicks::IsHighResClockWorking() {
450 return HighResNowSingleton::GetInstance()->IsUsingHighResClock();