| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 | 5 |
| 6 // Windows Timer Primer | 6 // Windows Timer Primer |
| 7 // | 7 // |
| 8 // A good article: http://www.ddj.com/windows/184416651 | 8 // A good article: http://www.ddj.com/windows/184416651 |
| 9 // A good mozilla bug: http://bugzilla.mozilla.org/show_bug.cgi?id=363258 | 9 // A good mozilla bug: http://bugzilla.mozilla.org/show_bug.cgi?id=363258 |
| 10 // | 10 // |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 #pragma comment(lib, "winmm.lib") | 39 #pragma comment(lib, "winmm.lib") |
| 40 #include <windows.h> | 40 #include <windows.h> |
| 41 #include <mmsystem.h> | 41 #include <mmsystem.h> |
| 42 | 42 |
| 43 #include "base/basictypes.h" | 43 #include "base/basictypes.h" |
| 44 #include "base/lock.h" | 44 #include "base/lock.h" |
| 45 #include "base/logging.h" | 45 #include "base/logging.h" |
| 46 #include "base/cpu.h" | 46 #include "base/cpu.h" |
| 47 #include "base/singleton.h" | 47 #include "base/singleton.h" |
| 48 #include "base/system_monitor.h" | |
| 49 | 48 |
| 50 using base::Time; | 49 using base::Time; |
| 51 using base::TimeDelta; | 50 using base::TimeDelta; |
| 52 using base::TimeTicks; | 51 using base::TimeTicks; |
| 53 | 52 |
| 54 namespace { | 53 namespace { |
| 55 | 54 |
| 56 // From MSDN, FILETIME "Contains a 64-bit value representing the number of | 55 // From MSDN, FILETIME "Contains a 64-bit value representing the number of |
| 57 // 100-nanosecond intervals since January 1, 1601 (UTC)." | 56 // 100-nanosecond intervals since January 1, 1601 (UTC)." |
| 58 int64 FileTimeToMicroseconds(const FILETIME& ft) { | 57 int64 FileTimeToMicroseconds(const FILETIME& ft) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 81 const int kMaxMillisecondsToAvoidDrift = 60 * Time::kMillisecondsPerSecond; | 80 const int kMaxMillisecondsToAvoidDrift = 60 * Time::kMillisecondsPerSecond; |
| 82 | 81 |
| 83 int64 initial_time = 0; | 82 int64 initial_time = 0; |
| 84 TimeTicks initial_ticks; | 83 TimeTicks initial_ticks; |
| 85 | 84 |
| 86 void InitializeClock() { | 85 void InitializeClock() { |
| 87 initial_ticks = TimeTicks::Now(); | 86 initial_ticks = TimeTicks::Now(); |
| 88 initial_time = CurrentWallclockMicroseconds(); | 87 initial_time = CurrentWallclockMicroseconds(); |
| 89 } | 88 } |
| 90 | 89 |
| 91 class HighResolutionTimerManager : public base::SystemMonitor::PowerObserver { | |
| 92 public: | |
| 93 ~HighResolutionTimerManager() { | |
| 94 StopMonitoring(); | |
| 95 UseHiResClock(false); | |
| 96 } | |
| 97 | |
| 98 void Enable() { | |
| 99 StopMonitoring(); | |
| 100 UseHiResClock(true); | |
| 101 } | |
| 102 | |
| 103 void StartMonitoring() { | |
| 104 if (is_monitoring_) | |
| 105 return; | |
| 106 is_monitoring_ = true; | |
| 107 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); | |
| 108 system_monitor->AddObserver(this); | |
| 109 UseHiResClock(!system_monitor->BatteryPower()); | |
| 110 } | |
| 111 | |
| 112 void StopMonitoring() { | |
| 113 if (!is_monitoring_) | |
| 114 return; | |
| 115 is_monitoring_ = false; | |
| 116 base::SystemMonitor* system_monitor = base::SystemMonitor::Get(); | |
| 117 if (system_monitor) | |
| 118 system_monitor->RemoveObserver(this); | |
| 119 } | |
| 120 | |
| 121 // Interfaces for monitoring Power changes. | |
| 122 void OnPowerStateChange(bool on_battery_power) { | |
| 123 UseHiResClock(!on_battery_power); | |
| 124 } | |
| 125 | |
| 126 private: | |
| 127 HighResolutionTimerManager() | |
| 128 : is_monitoring_(false), | |
| 129 hi_res_clock_enabled_(false) { | |
| 130 } | |
| 131 friend struct DefaultSingletonTraits<HighResolutionTimerManager>; | |
| 132 | |
| 133 // Enable or disable the faster multimedia timer. | |
| 134 void UseHiResClock(bool enabled) { | |
| 135 if (enabled == hi_res_clock_enabled_) | |
| 136 return; | |
| 137 if (enabled) | |
| 138 timeBeginPeriod(1); | |
| 139 else | |
| 140 timeEndPeriod(1); | |
| 141 hi_res_clock_enabled_ = enabled; | |
| 142 } | |
| 143 | |
| 144 bool is_monitoring_; | |
| 145 bool hi_res_clock_enabled_; | |
| 146 | |
| 147 DISALLOW_COPY_AND_ASSIGN(HighResolutionTimerManager); | |
| 148 }; | |
| 149 | |
| 150 } // namespace | 90 } // namespace |
| 151 | 91 |
| 152 // Time ----------------------------------------------------------------------- | 92 // Time ----------------------------------------------------------------------- |
| 153 | 93 |
| 154 // The internal representation of Time uses FILETIME, whose epoch is 1601-01-01 | 94 // The internal representation of Time uses FILETIME, whose epoch is 1601-01-01 |
| 155 // 00:00:00 UTC. ((1970-1601)*365+89)*24*60*60*1000*1000, where 89 is the | 95 // 00:00:00 UTC. ((1970-1601)*365+89)*24*60*60*1000*1000, where 89 is the |
| 156 // number of leap year days between 1601 and 1970: (1970-1601)/4 excluding | 96 // number of leap year days between 1601 and 1970: (1970-1601)/4 excluding |
| 157 // 1700, 1800, and 1900. | 97 // 1700, 1800, and 1900. |
| 158 // static | 98 // static |
| 159 const int64 Time::kTimeTToMicrosecondsOffset = GG_INT64_C(11644473600000000); | 99 const int64 Time::kTimeTToMicrosecondsOffset = GG_INT64_C(11644473600000000); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 return Time(FileTimeToMicroseconds(ft)); | 141 return Time(FileTimeToMicroseconds(ft)); |
| 202 } | 142 } |
| 203 | 143 |
| 204 FILETIME Time::ToFileTime() const { | 144 FILETIME Time::ToFileTime() const { |
| 205 FILETIME utc_ft; | 145 FILETIME utc_ft; |
| 206 MicrosecondsToFileTime(us_, &utc_ft); | 146 MicrosecondsToFileTime(us_, &utc_ft); |
| 207 return utc_ft; | 147 return utc_ft; |
| 208 } | 148 } |
| 209 | 149 |
| 210 // static | 150 // static |
| 211 void Time::StartSystemMonitorObserver() { | 151 bool Time::UseHighResolutionTimer(bool use) { |
| 212 Singleton<HighResolutionTimerManager>()->StartMonitoring(); | 152 // TODO(mbelshe): Make sure that switching the system timer resolution |
| 153 // doesn't break Timer firing order etc. An example test would be to have |
| 154 // two threads. One would have a bunch of timers, and another would turn the |
| 155 // high resolution timer on and off. |
| 156 |
| 157 MMRESULT result; |
| 158 if (use) |
| 159 result = timeBeginPeriod(1); |
| 160 else |
| 161 result = timeEndPeriod(1); |
| 162 return (result == TIMERR_NOERROR); |
| 213 } | 163 } |
| 214 | 164 |
| 215 // static | 165 // static |
| 216 void Time::EnableHiResClockForTests() { | |
| 217 Singleton<HighResolutionTimerManager>()->Enable(); | |
| 218 } | |
| 219 | |
| 220 // static | |
| 221 Time Time::FromExploded(bool is_local, const Exploded& exploded) { | 166 Time Time::FromExploded(bool is_local, const Exploded& exploded) { |
| 222 // Create the system struct representing our exploded time. It will either be | 167 // Create the system struct representing our exploded time. It will either be |
| 223 // in local time or UTC. | 168 // in local time or UTC. |
| 224 SYSTEMTIME st; | 169 SYSTEMTIME st; |
| 225 st.wYear = exploded.year; | 170 st.wYear = exploded.year; |
| 226 st.wMonth = exploded.month; | 171 st.wMonth = exploded.month; |
| 227 st.wDayOfWeek = exploded.day_of_week; | 172 st.wDayOfWeek = exploded.day_of_week; |
| 228 st.wDay = exploded.day_of_month; | 173 st.wDay = exploded.day_of_month; |
| 229 st.wHour = exploded.hour; | 174 st.wHour = exploded.hour; |
| 230 st.wMinute = exploded.minute; | 175 st.wMinute = exploded.minute; |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 | 381 |
| 437 // static | 382 // static |
| 438 TimeTicks TimeTicks::Now() { | 383 TimeTicks TimeTicks::Now() { |
| 439 return TimeTicks() + Singleton<NowSingleton>::get()->Now(); | 384 return TimeTicks() + Singleton<NowSingleton>::get()->Now(); |
| 440 } | 385 } |
| 441 | 386 |
| 442 // static | 387 // static |
| 443 TimeTicks TimeTicks::HighResNow() { | 388 TimeTicks TimeTicks::HighResNow() { |
| 444 return TimeTicks() + Singleton<HighResNowSingleton>::get()->Now(); | 389 return TimeTicks() + Singleton<HighResNowSingleton>::get()->Now(); |
| 445 } | 390 } |
| OLD | NEW |