15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows Timer Primer
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A good article:  http://www.ddj.com/windows/184416651
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A good mozilla bug:  http://bugzilla.mozilla.org/show_bug.cgi?id=363258
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The default windows timer, GetSystemTimeAsFileTime is not very precise.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It is only good to ~15.5ms.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// QueryPerformanceCounter is the logical choice for a high-precision timer.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// However, it is known to be buggy on some hardware.  Specifically, it can
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sometimes "jump".  On laptops, QPC can also be very expensive to call.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It's 3-4x slower than timeGetTime() on desktops, but can be 10x slower
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// on laptops.  A unittest exists which will show the relative cost of various
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// timers on any system.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The next logical choice is timeGetTime().  timeGetTime has a precision of
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1ms, but only if you call APIs (timeBeginPeriod()) which affect all other
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// applications on the system.  By default, precision is only 15.5ms.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Unfortunately, we don't want to call timeBeginPeriod because we don't
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// want to affect other applications.  Further, on mobile platforms, use of
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// faster multimedia timers can hurt battery life.  See the intel
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// article about this here:
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://softwarecommunity.intel.com/articles/eng/1086.htm
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// To work around all this, we're going to generally use timeGetTime().  We
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will only increase the system-wide timer if we're not running on battery
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// power.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma comment(lib, "winmm.lib")
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mmsystem.h>
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/cpu.h"
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/lazy_instance.h"
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/logging.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// From MSDN, FILETIME "Contains a 64-bit value representing the number of
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 100-nanosecond intervals since January 1, 1601 (UTC)."
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 FileTimeToMicroseconds(const FILETIME& ft) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to bit_cast to fix alignment, then divide by 10 to convert
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 100-nanoseconds to milliseconds. This only works on little-endian
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // machines.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bit_cast<int64, FILETIME>(ft) / 10;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MicrosecondsToFileTime(int64 us, FILETIME* ft) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GE(us, 0LL) << "Time is less than 0, negative values are not "
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "representable in FILETIME";
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Multiply by 10 to convert milliseconds to 100-nanoseconds. Bit_cast will
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handle alignment problems. This only works on little-endian machines.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *ft = bit_cast<FILETIME, int64>(us * 10);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 CurrentWallclockMicroseconds() {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FILETIME ft;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ::GetSystemTimeAsFileTime(&ft);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return FileTimeToMicroseconds(ft);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Time between resampling the un-granular clock for this API.  60 seconds.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxMillisecondsToAvoidDrift = 60 * Time::kMillisecondsPerSecond;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 initial_time = 0;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks initial_ticks;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitializeClock() {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_ticks = TimeTicks::Now();
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initial_time = CurrentWallclockMicroseconds();
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The two values that ActivateHighResolutionTimer uses to set the systemwide
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// timer interrupt frequency on Windows. It controls how precise timers are
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// but also has a big impact on battery life.
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kMinTimerIntervalHighResMs = 1;
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciconst int kMinTimerIntervalLowResMs = 4;
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Track if kMinTimerIntervalHighResMs or kMinTimerIntervalLowResMs is active.
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool g_high_res_timer_enabled = false;
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// How many times the high resolution timer has been called.
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciuint32_t g_high_res_timer_count = 0;
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The lock to control access to the above two variables.
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibase::LazyInstance<base::Lock>::Leaky g_high_res_lock =
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LAZY_INSTANCE_INITIALIZER;
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Time -----------------------------------------------------------------------
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The internal representation of Time uses FILETIME, whose epoch is 1601-01-01
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 00:00:00 UTC.  ((1970-1601)*365+89)*24*60*60*1000*1000, where 89 is the
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// number of leap year days between 1601 and 1970: (1970-1601)/4 excluding
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1700, 1800, and 1900.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 Time::kTimeTToMicrosecondsOffset = GG_INT64_C(11644473600000000);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Time Time::Now() {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (initial_time == 0)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InitializeClock();
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We implement time using the high-resolution timers so that we can get
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // timeouts which are smaller than 10-15ms.  If we just used
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CurrentWallclockMicroseconds(), we'd have the less-granular timer.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // To make this work, we initialize the clock (initial_time) and the
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // counter (initial_ctr).  To compute the initial time, we can check
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the number of ticks that have elapsed, and compute the delta.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // To avoid any drift, we periodically resync the counters to the system
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // clock.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (true) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TimeTicks ticks = TimeTicks::Now();
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Calculate the time elapsed since we started our timer
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TimeDelta elapsed = ticks - initial_ticks;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check if enough time has elapsed that we need to resync the clock.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (elapsed.InMilliseconds() > kMaxMillisecondsToAvoidDrift) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InitializeClock();
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Time(elapsed + Time(initial_time));
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Time Time::NowFromSystemTime() {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Force resync.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitializeClock();
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Time(initial_time);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Time Time::FromFileTime(FILETIME ft) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bit_cast<int64, FILETIME>(ft) == 0)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Time();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ft.dwHighDateTime == std::numeric_limits<DWORD>::max() &&
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ft.dwLowDateTime == std::numeric_limits<DWORD>::max())
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Max();
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Time(FileTimeToMicroseconds(ft));
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FILETIME Time::ToFileTime() const {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_null())
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return bit_cast<FILETIME, int64>(0);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_max()) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FILETIME result;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.dwHighDateTime = std::numeric_limits<DWORD>::max();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.dwLowDateTime = std::numeric_limits<DWORD>::max();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FILETIME utc_ft;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MicrosecondsToFileTime(us_, &utc_ft);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return utc_ft;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Time::EnableHighResolutionTimer(bool enable) {
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::AutoLock lock(g_high_res_lock.Get());
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (g_high_res_timer_enabled == enable)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  g_high_res_timer_enabled = enable;
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!g_high_res_timer_count)
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Since g_high_res_timer_count != 0, an ActivateHighResolutionTimer(true)
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // was called which called timeBeginPeriod with g_high_res_timer_enabled
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // with a value which is the opposite of |enable|. With that information we
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // call timeEndPeriod with the same value used in timeBeginPeriod and
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // therefore undo the period effect.
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (enable) {
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    timeEndPeriod(kMinTimerIntervalLowResMs);
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    timeBeginPeriod(kMinTimerIntervalHighResMs);
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    timeEndPeriod(kMinTimerIntervalHighResMs);
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    timeBeginPeriod(kMinTimerIntervalLowResMs);
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Time::ActivateHighResolutionTimer(bool activating) {
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // We only do work on the transition from zero to one or one to zero so we
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // can easily undo the effect (if necessary) when EnableHighResolutionTimer is
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // called.
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const uint32_t max = std::numeric_limits<uint32_t>::max();
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::AutoLock lock(g_high_res_lock.Get());
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UINT period = g_high_res_timer_enabled ? kMinTimerIntervalHighResMs
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                         : kMinTimerIntervalLowResMs;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (activating) {
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(g_high_res_timer_count != max);
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ++g_high_res_timer_count;
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (g_high_res_timer_count == 1)
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      timeBeginPeriod(period);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(g_high_res_timer_count != 0);
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    --g_high_res_timer_count;
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (g_high_res_timer_count == 0)
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      timeEndPeriod(period);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return (period == kMinTimerIntervalHighResMs);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Time::IsHighResolutionTimerInUse() {
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::AutoLock lock(g_high_res_lock.Get());
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return g_high_res_timer_enabled && g_high_res_timer_count > 0;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Time Time::FromExploded(bool is_local, const Exploded& exploded) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the system struct representing our exploded time. It will either be
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in local time or UTC.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SYSTEMTIME st;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  st.wYear = exploded.year;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  st.wMonth = exploded.month;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  st.wDayOfWeek = exploded.day_of_week;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  st.wDay = exploded.day_of_month;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  st.wHour = exploded.hour;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  st.wMinute = exploded.minute;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  st.wSecond = exploded.second;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  st.wMilliseconds = exploded.millisecond;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FILETIME ft;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = true;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that it's in UTC.
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_local) {
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SYSTEMTIME utc_st;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    success = TzSpecificLocalTimeToSystemTime(NULL, &st, &utc_st) &&
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              SystemTimeToFileTime(&utc_st, &ft);
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    success = !!SystemTimeToFileTime(&st, &ft);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success) {
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Unable to convert time";
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Time(0);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Time(FileTimeToMicroseconds(ft));
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Time::Explode(bool is_local, Exploded* exploded) const {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (us_ < 0LL) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We are not able to convert it to FILETIME.
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ZeroMemory(exploded, sizeof(*exploded));
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FILETIME in UTC.
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FILETIME utc_ft;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MicrosecondsToFileTime(us_, &utc_ft);
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FILETIME in local time if necessary.
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = true;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // FILETIME in SYSTEMTIME (exploded).
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SYSTEMTIME st = {0};
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_local) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SYSTEMTIME utc_st;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We don't use FileTimeToLocalFileTime here, since it uses the current
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // settings for the time zone and daylight saving time. Therefore, if it is
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // daylight saving time, it will take daylight saving time into account,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // even if the time you are converting is in standard time.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    success = FileTimeToSystemTime(&utc_ft, &utc_st) &&
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              SystemTimeToTzSpecificLocalTime(NULL, &utc_st, &st);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    success = !!FileTimeToSystemTime(&utc_ft, &st);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED() << "Unable to convert time, don't know why";
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ZeroMemory(exploded, sizeof(*exploded));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->year = st.wYear;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->month = st.wMonth;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->day_of_week = st.wDayOfWeek;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->day_of_month = st.wDay;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->hour = st.wHour;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->minute = st.wMinute;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->second = st.wSecond;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exploded->millisecond = st.wMilliseconds;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TimeTicks ------------------------------------------------------------------
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We define a wrapper to adapt between the __stdcall and __cdecl call of the
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mock function, and to avoid a static constructor.  Assigning an import to a
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function pointer directly would require setup code to fetch from the IAT.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD timeGetTimeWrapper() {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return timeGetTime();
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD (*tick_function)(void) = &timeGetTimeWrapper;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Accumulation of time lost due to rollover (in milliseconds).
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 rollover_ms = 0;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The last timeGetTime value we saw, to detect rollover.
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD last_seen_now = 0;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Lock protecting rollover_ms and last_seen_now.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: this is a global object, and we usually avoid these. However, the time
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// code is low-level, and we don't want to use Singletons here (it would be too
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// easy to use a Singleton without even knowing it, and that may lead to many
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// gotchas). Its impact on startup time should be negligible due to low-level
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// nature of time code.
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Lock rollover_lock;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We use timeGetTime() to implement TimeTicks::Now().  This can be problematic
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// because it returns the number of milliseconds since Windows has started,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which will roll over the 32-bit value every ~49 days.  We try to track
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rollover ourselves, which works if TimeTicks::Now() is called at least every
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 49 days.
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeDelta RolloverProtectedNow() {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::AutoLock locked(rollover_lock);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should hold the lock while calling tick_function to make sure that
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we keep last_seen_now stay correctly in sync.
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD now = tick_function();
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (now < last_seen_now)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rollover_ms += 0x100000000I64;  // ~49.7 days.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_seen_now = now;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TimeDelta::FromMilliseconds(now + rollover_ms);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool IsBuggyAthlon(const base::CPU& cpu) {
34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is
34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // unreliable.  Fallback to low-res clock.
34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15;
34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Overview of time counters:
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (1) CPU cycle counter. (Retrieved via RDTSC)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The CPU counter provides the highest resolution time stamp and is the least
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// expensive to retrieve. However, the CPU counter is unreliable and should not
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be used in production. Its biggest issue is that it is per processor and it
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is not synchronized between processors. Also, on some computers, the counters
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will change frequency due to thermal and power changes, and stop in some
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// states.
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (2) QueryPerformanceCounter (QPC). The QPC counter provides a high-
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// resolution (100 nanoseconds) time stamp but is comparatively more expensive
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to retrieve. What QueryPerformanceCounter actually does is up to the HAL.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (with some help from ACPI).
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// According to http://blogs.msdn.com/oldnewthing/archive/2005/09/02/459952.aspx
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the worst case, it gets the counter from the rollover interrupt on the
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// programmable interrupt timer. In best cases, the HAL may conclude that the
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RDTSC counter runs at a constant frequency, then it uses that instead. On
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// multiprocessor machines, it will try to verify the values returned from
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RDTSC on each processor are consistent with each other, and apply a handful
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of workarounds for known buggy hardware. In other words, QPC is supposed to
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// give consistent result on a multiprocessor computer, but it is unreliable in
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reality due to bugs in BIOS or HAL on some, especially old computers.
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// With recent updates on HAL and newer BIOS, QPC is getting more reliable but
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it should be used with caution.
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (3) System time. The system time provides a low-resolution (typically 10ms
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to 55 milliseconds) time stamp but is comparatively less expensive to
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// retrieve and more reliable.
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HighResNowSingleton {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  HighResNowSingleton()
3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : ticks_per_second_(0),
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        skew_(0) {
381cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    base::CPU cpu;
383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (IsBuggyAthlon(cpu))
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Synchronize the QPC clock with GetSystemTimeAsFileTime.
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LARGE_INTEGER ticks_per_sec = {0};
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!QueryPerformanceFrequency(&ticks_per_sec))
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return; // QPC is not available.
3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ticks_per_second_ = ticks_per_sec.QuadPart;
3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    skew_ = UnreliableNow() - ReliableNow();
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool IsUsingHighResClock() {
3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return ticks_per_second_ != 0;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDelta Now() {
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (IsUsingHighResClock())
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return TimeDelta::FromMicroseconds(UnreliableNow());
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Just fallback to the slower clock.
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return RolloverProtectedNow();
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 GetQPCDriftMicroseconds() {
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!IsUsingHighResClock())
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 0;
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return abs((UnreliableNow() - ReliableNow()) - skew_);
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 QPCValueToMicroseconds(LONGLONG qpc_value) {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ticks_per_second_)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 0;
4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // If the QPC Value is below the overflow threshold, we proceed with
4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // simple multiply and divide.
4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (qpc_value < Time::kQPCOverflowThreshold)
4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return qpc_value * Time::kMicrosecondsPerSecond / ticks_per_second_;
4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Otherwise, calculate microseconds in a round about manner to avoid
4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // overflow and precision issues.
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 whole_seconds = qpc_value / ticks_per_second_;
4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    int64 leftover_ticks = qpc_value - (whole_seconds * ticks_per_second_);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 microseconds = (whole_seconds * Time::kMicrosecondsPerSecond) +
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         ((leftover_ticks * Time::kMicrosecondsPerSecond) /
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          ticks_per_second_);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return microseconds;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the number of microseconds since boot in an unreliable fashion.
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 UnreliableNow() {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LARGE_INTEGER now;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    QueryPerformanceCounter(&now);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return QPCValueToMicroseconds(now.QuadPart);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the number of microseconds since boot in a reliable fashion.
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 ReliableNow() {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return RolloverProtectedNow().InMicroseconds();
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 ticks_per_second_;  // 0 indicates QPF failed and we're broken.
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 skew_;  // Skew between lo-res and hi-res clocks (for debugging).
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static base::LazyInstance<HighResNowSingleton>::Leaky
448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    leaky_high_res_now_singleton = LAZY_INSTANCE_INITIALIZER;
449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)HighResNowSingleton* GetHighResNowSingleton() {
451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return leaky_high_res_now_singleton.Pointer();
452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
45458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TimeDelta HighResNowWrapper() {
455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return GetHighResNowSingleton()->Now();
45658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
45758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
45858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)typedef TimeDelta (*NowFunction)(void);
45958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
46058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool CPUReliablySupportsHighResTime() {
46158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::CPU cpu;
4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!cpu.has_non_stop_time_stamp_counter() ||
4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      !GetHighResNowSingleton()->IsUsingHighResClock())
46458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
46558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
46658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (IsBuggyAthlon(cpu))
46758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return false;
46858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
46958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return true;
47058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
47158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTimeDelta InitialNowFunction();
4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivolatile NowFunction now_function = InitialNowFunction;
4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTimeDelta InitialNowFunction() {
4771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!CPUReliablySupportsHighResTime()) {
4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    InterlockedExchangePointer(
4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        reinterpret_cast<void* volatile*>(&now_function),
4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        &RolloverProtectedNow);
4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return RolloverProtectedNow();
4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  InterlockedExchangePointer(
4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        reinterpret_cast<void* volatile*>(&now_function),
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        &HighResNowWrapper);
4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return HighResNowWrapper();
4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks::TickFunctionType TimeTicks::SetMockTickFunction(
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TickFunctionType ticker) {
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AutoLock locked(rollover_lock);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TickFunctionType old = tick_function;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tick_function = ticker;
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  rollover_ms = 0;
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  last_seen_now = 0;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return old;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks TimeTicks::Now() {
50458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return TimeTicks() + now_function();
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks TimeTicks::HighResNow() {
509cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return TimeTicks() + HighResNowWrapper();
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool TimeTicks::IsHighResNowFastAndReliable() {
5144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return CPUReliablySupportsHighResTime();
5154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
5164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
5174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static
518a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TimeTicks TimeTicks::ThreadNow() {
519a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  NOTREACHED();
520a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return TimeTicks();
521a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
522a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
523a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks TimeTicks::NowFromSystemTraceTime() {
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return HighResNow();
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 TimeTicks::GetQPCDriftMicroseconds() {
530cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return GetHighResNowSingleton()->GetQPCDriftMicroseconds();
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks TimeTicks::FromQPCValue(LONGLONG qpc_value) {
535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return TimeTicks(GetHighResNowSingleton()->QPCValueToMicroseconds(qpc_value));
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TimeTicks::IsHighResClockWorking() {
540cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return GetHighResNowSingleton()->IsUsingHighResClock();
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TimeTicks TimeTicks::UnprotectedNow() {
54458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (now_function == HighResNowWrapper) {
54558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return Now();
54658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  } else {
54758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    return TimeTicks() + TimeDelta::FromMilliseconds(timeGetTime());
54858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
54958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
55058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TimeDelta ------------------------------------------------------------------
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeDelta TimeDelta::FromQPCValue(LONGLONG qpc_value) {
555cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return TimeDelta(GetHighResNowSingleton()->QPCValueToMicroseconds(qpc_value));
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
557