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 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// power. Using timeBeginPeriod(1) is a requirement in order to make our 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message loop waits have the same resolution that our time measurements 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// do. Otherwise, WaitForSingleObject(..., 1) will no less than 15ms when 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// there is nothing else to waken the Wait. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma comment(lib, "winmm.lib") 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mmsystem.h> 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/cpu.h" 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/logging.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/singleton.h" 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// From MSDN, FILETIME "Contains a 64-bit value representing the number of 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 100-nanosecond intervals since January 1, 1601 (UTC)." 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 FileTimeToMicroseconds(const FILETIME& ft) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Need to bit_cast to fix alignment, then divide by 10 to convert 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 100-nanoseconds to milliseconds. This only works on little-endian 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // machines. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bit_cast<int64, FILETIME>(ft) / 10; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MicrosecondsToFileTime(int64 us, FILETIME* ft) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(us, 0LL) << "Time is less than 0, negative values are not " 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "representable in FILETIME"; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Multiply by 10 to convert milliseconds to 100-nanoseconds. Bit_cast will 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // handle alignment problems. This only works on little-endian machines. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ft = bit_cast<FILETIME, int64>(us * 10); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 CurrentWallclockMicroseconds() { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILETIME ft; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetSystemTimeAsFileTime(&ft); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return FileTimeToMicroseconds(ft); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Time between resampling the un-granular clock for this API. 60 seconds. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxMillisecondsToAvoidDrift = 60 * Time::kMillisecondsPerSecond; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 initial_time = 0; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks initial_ticks; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitializeClock() { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_ticks = TimeTicks::Now(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_time = CurrentWallclockMicroseconds(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Time ----------------------------------------------------------------------- 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The internal representation of Time uses FILETIME, whose epoch is 1601-01-01 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 00:00:00 UTC. ((1970-1601)*365+89)*24*60*60*1000*1000, where 89 is the 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// number of leap year days between 1601 and 1970: (1970-1601)/4 excluding 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1700, 1800, and 1900. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 Time::kTimeTToMicrosecondsOffset = GG_INT64_C(11644473600000000); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Time::high_resolution_timer_enabled_ = false; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Time::high_resolution_timer_activated_ = 0; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Time Time::Now() { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (initial_time == 0) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeClock(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We implement time using the high-resolution timers so that we can get 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // timeouts which are smaller than 10-15ms. If we just used 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CurrentWallclockMicroseconds(), we'd have the less-granular timer. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To make this work, we initialize the clock (initial_time) and the 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // counter (initial_ctr). To compute the initial time, we can check 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the number of ticks that have elapsed, and compute the delta. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To avoid any drift, we periodically resync the counters to the system 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // clock. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks ticks = TimeTicks::Now(); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Calculate the time elapsed since we started our timer 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta elapsed = ticks - initial_ticks; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if enough time has elapsed that we need to resync the clock. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (elapsed.InMilliseconds() > kMaxMillisecondsToAvoidDrift) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeClock(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Time(elapsed + Time(initial_time)); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Time Time::NowFromSystemTime() { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Force resync. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeClock(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Time(initial_time); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Time Time::FromFileTime(FILETIME ft) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bit_cast<int64, FILETIME>(ft) == 0) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Time(); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ft.dwHighDateTime == std::numeric_limits<DWORD>::max() && 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ft.dwLowDateTime == std::numeric_limits<DWORD>::max()) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Max(); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Time(FileTimeToMicroseconds(ft)); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FILETIME Time::ToFileTime() const { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_null()) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return bit_cast<FILETIME, int64>(0); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_max()) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILETIME result; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.dwHighDateTime = std::numeric_limits<DWORD>::max(); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.dwLowDateTime = std::numeric_limits<DWORD>::max(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILETIME utc_ft; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MicrosecondsToFileTime(us_, &utc_ft); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return utc_ft; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Time::EnableHighResolutionTimer(bool enable) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test for single-threaded access. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static PlatformThreadId my_thread = PlatformThread::CurrentId(); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(PlatformThread::CurrentId() == my_thread); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (high_resolution_timer_enabled_ == enable) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) high_resolution_timer_enabled_ = enable; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Time::ActivateHighResolutionTimer(bool activating) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!high_resolution_timer_enabled_ && activating) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Using anything other than 1ms makes timers granular 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to that interval. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMinTimerIntervalMs = 1; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MMRESULT result; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (activating) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = timeBeginPeriod(kMinTimerIntervalMs); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) high_resolution_timer_activated_++; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = timeEndPeriod(kMinTimerIntervalMs); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) high_resolution_timer_activated_--; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result == TIMERR_NOERROR; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Time::IsHighResolutionTimerInUse() { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: we should track the high_resolution_timer_activated_ value 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // under a lock if we want it to be accurate in a system with multiple 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message loops. We don't do that - because we don't want to take the 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // expense of a lock for this. We *only* track this value so that unit 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tests can see if the high resolution timer is on or off. 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return high_resolution_timer_enabled_ && 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) high_resolution_timer_activated_ > 0; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Time Time::FromExploded(bool is_local, const Exploded& exploded) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the system struct representing our exploded time. It will either be 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in local time or UTC. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYSTEMTIME st; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) st.wYear = exploded.year; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) st.wMonth = exploded.month; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) st.wDayOfWeek = exploded.day_of_week; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) st.wDay = exploded.day_of_month; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) st.wHour = exploded.hour; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) st.wMinute = exploded.minute; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) st.wSecond = exploded.second; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) st.wMilliseconds = exploded.millisecond; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILETIME ft; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = true; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that it's in UTC. 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_local) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYSTEMTIME utc_st; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = TzSpecificLocalTimeToSystemTime(NULL, &st, &utc_st) && 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SystemTimeToFileTime(&utc_st, &ft); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = !!SystemTimeToFileTime(&st, &ft); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!success) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unable to convert time"; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Time(0); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Time(FileTimeToMicroseconds(ft)); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Time::Explode(bool is_local, Exploded* exploded) const { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (us_ < 0LL) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We are not able to convert it to FILETIME. 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ZeroMemory(exploded, sizeof(*exploded)); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FILETIME in UTC. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILETIME utc_ft; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MicrosecondsToFileTime(us_, &utc_ft); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FILETIME in local time if necessary. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = true; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FILETIME in SYSTEMTIME (exploded). 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYSTEMTIME st; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_local) { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SYSTEMTIME utc_st; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't use FileTimeToLocalFileTime here, since it uses the current 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // settings for the time zone and daylight saving time. Therefore, if it is 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // daylight saving time, it will take daylight saving time into account, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // even if the time you are converting is in standard time. 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = FileTimeToSystemTime(&utc_ft, &utc_st) && 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SystemTimeToTzSpecificLocalTime(NULL, &utc_st, &st); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = !!FileTimeToSystemTime(&utc_ft, &st); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!success) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unable to convert time, don't know why"; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ZeroMemory(exploded, sizeof(*exploded)); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exploded->year = st.wYear; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exploded->month = st.wMonth; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exploded->day_of_week = st.wDayOfWeek; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exploded->day_of_month = st.wDay; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exploded->hour = st.wHour; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exploded->minute = st.wMinute; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exploded->second = st.wSecond; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exploded->millisecond = st.wMilliseconds; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TimeTicks ------------------------------------------------------------------ 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We define a wrapper to adapt between the __stdcall and __cdecl call of the 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mock function, and to avoid a static constructor. Assigning an import to a 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// function pointer directly would require setup code to fetch from the IAT. 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD timeGetTimeWrapper() { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return timeGetTime(); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD (*tick_function)(void) = &timeGetTimeWrapper; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Accumulation of time lost due to rollover (in milliseconds). 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 rollover_ms = 0; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The last timeGetTime value we saw, to detect rollover. 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DWORD last_seen_now = 0; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Lock protecting rollover_ms and last_seen_now. 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note: this is a global object, and we usually avoid these. However, the time 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// code is low-level, and we don't want to use Singletons here (it would be too 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// easy to use a Singleton without even knowing it, and that may lead to many 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// gotchas). Its impact on startup time should be negligible due to low-level 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// nature of time code. 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Lock rollover_lock; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We use timeGetTime() to implement TimeTicks::Now(). This can be problematic 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// because it returns the number of milliseconds since Windows has started, 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which will roll over the 32-bit value every ~49 days. We try to track 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rollover ourselves, which works if TimeTicks::Now() is called at least every 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 49 days. 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeDelta RolloverProtectedNow() { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(rollover_lock); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should hold the lock while calling tick_function to make sure that 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we keep last_seen_now stay correctly in sync. 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD now = tick_function(); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (now < last_seen_now) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rollover_ms += 0x100000000I64; // ~49.7 days. 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_seen_now = now; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta::FromMilliseconds(now + rollover_ms); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool IsBuggyAthlon(const base::CPU& cpu) { 32658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is 32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // unreliable. Fallback to low-res clock. 32858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15; 32958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Overview of time counters: 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (1) CPU cycle counter. (Retrieved via RDTSC) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The CPU counter provides the highest resolution time stamp and is the least 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// expensive to retrieve. However, the CPU counter is unreliable and should not 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be used in production. Its biggest issue is that it is per processor and it 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is not synchronized between processors. Also, on some computers, the counters 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will change frequency due to thermal and power changes, and stop in some 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// states. 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (2) QueryPerformanceCounter (QPC). The QPC counter provides a high- 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// resolution (100 nanoseconds) time stamp but is comparatively more expensive 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to retrieve. What QueryPerformanceCounter actually does is up to the HAL. 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (with some help from ACPI). 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// According to http://blogs.msdn.com/oldnewthing/archive/2005/09/02/459952.aspx 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the worst case, it gets the counter from the rollover interrupt on the 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// programmable interrupt timer. In best cases, the HAL may conclude that the 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RDTSC counter runs at a constant frequency, then it uses that instead. On 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// multiprocessor machines, it will try to verify the values returned from 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RDTSC on each processor are consistent with each other, and apply a handful 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of workarounds for known buggy hardware. In other words, QPC is supposed to 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// give consistent result on a multiprocessor computer, but it is unreliable in 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reality due to bugs in BIOS or HAL on some, especially old computers. 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// With recent updates on HAL and newer BIOS, QPC is getting more reliable but 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it should be used with caution. 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (3) System time. The system time provides a low-resolution (typically 10ms 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to 55 milliseconds) time stamp but is comparatively less expensive to 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// retrieve and more reliable. 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HighResNowSingleton { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static HighResNowSingleton* GetInstance() { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Singleton<HighResNowSingleton>::get(); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsUsingHighResClock() { 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ticks_per_second_ != 0.0; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DisableHighResClock() { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ticks_per_second_ = 0.0; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta Now() { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsUsingHighResClock()) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta::FromMicroseconds(UnreliableNow()); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Just fallback to the slower clock. 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RolloverProtectedNow(); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 GetQPCDriftMicroseconds() { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsUsingHighResClock()) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return abs((UnreliableNow() - ReliableNow()) - skew_); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 QPCValueToMicroseconds(LONGLONG qpc_value) { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ticks_per_second_) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Intentionally calculate microseconds in a round about manner to avoid 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // overflow and precision issues. Think twice before simplifying! 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 whole_seconds = qpc_value / ticks_per_second_; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 leftover_ticks = qpc_value % ticks_per_second_; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 microseconds = (whole_seconds * Time::kMicrosecondsPerSecond) + 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((leftover_ticks * Time::kMicrosecondsPerSecond) / 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ticks_per_second_); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return microseconds; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HighResNowSingleton() 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ticks_per_second_(0), 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skew_(0) { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeClock(); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::CPU cpu; 40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (IsBuggyAthlon(cpu)) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DisableHighResClock(); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Synchronize the QPC clock with GetSystemTimeAsFileTime. 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InitializeClock() { 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LARGE_INTEGER ticks_per_sec = {0}; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!QueryPerformanceFrequency(&ticks_per_sec)) 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Broken, we don't guarantee this function works. 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ticks_per_second_ = ticks_per_sec.QuadPart; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skew_ = UnreliableNow() - ReliableNow(); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the number of microseconds since boot in an unreliable fashion. 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 UnreliableNow() { 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LARGE_INTEGER now; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueryPerformanceCounter(&now); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return QPCValueToMicroseconds(now.QuadPart); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the number of microseconds since boot in a reliable fashion. 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 ReliableNow() { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RolloverProtectedNow().InMicroseconds(); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 ticks_per_second_; // 0 indicates QPF failed and we're broken. 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 skew_; // Skew between lo-res and hi-res clocks (for debugging). 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend struct DefaultSingletonTraits<HighResNowSingleton>; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 44058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TimeDelta HighResNowWrapper() { 44158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return HighResNowSingleton::GetInstance()->Now(); 44258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 44358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 44458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)typedef TimeDelta (*NowFunction)(void); 44558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)NowFunction now_function = RolloverProtectedNow; 44658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 44758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool CPUReliablySupportsHighResTime() { 44858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::CPU cpu; 44958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!cpu.has_non_stop_time_stamp_counter()) 45058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 45158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 45258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (IsBuggyAthlon(cpu)) 45358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 45458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 45558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 45658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 45758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks::TickFunctionType TimeTicks::SetMockTickFunction( 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TickFunctionType ticker) { 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoLock locked(rollover_lock); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TickFunctionType old = tick_function; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tick_function = ticker; 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) rollover_ms = 0; 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last_seen_now = 0; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return old; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 47258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)bool TimeTicks::SetNowIsHighResNowIfSupported() { 47358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!CPUReliablySupportsHighResTime()) { 47458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 47558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 47658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 47758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) now_function = HighResNowWrapper; 47858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 47958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 48058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 48158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// static 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks TimeTicks::Now() { 48358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return TimeTicks() + now_function(); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks TimeTicks::HighResNow() { 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeTicks() + HighResNowSingleton::GetInstance()->Now(); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool TimeTicks::IsHighResNowFastAndReliable() { 4934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return CPUReliablySupportsHighResTime(); 4944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 4954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 497a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)TimeTicks TimeTicks::ThreadNow() { 498a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NOTREACHED(); 499a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return TimeTicks(); 500a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 501a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 502a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks TimeTicks::NowFromSystemTraceTime() { 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HighResNow(); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 TimeTicks::GetQPCDriftMicroseconds() { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HighResNowSingleton::GetInstance()->GetQPCDriftMicroseconds(); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeTicks TimeTicks::FromQPCValue(LONGLONG qpc_value) { 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeTicks( 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HighResNowSingleton::GetInstance()->QPCValueToMicroseconds(qpc_value)); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TimeTicks::IsHighResClockWorking() { 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return HighResNowSingleton::GetInstance()->IsUsingHighResClock(); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TimeTicks TimeTicks::UnprotectedNow() { 52458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (now_function == HighResNowWrapper) { 52558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return Now(); 52658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 52758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return TimeTicks() + TimeDelta::FromMilliseconds(timeGetTime()); 52858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 52958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 53058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TimeDelta ------------------------------------------------------------------ 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeDelta TimeDelta::FromQPCValue(LONGLONG qpc_value) { 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta( 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HighResNowSingleton::GetInstance()->QPCValueToMicroseconds(qpc_value)); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 538