Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(390)

Side by Side Diff: base/time_win.cc

Issue 113824: Do not monitor system power state during unit tests. (Closed)
Patch Set: Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 const int kMaxMillisecondsToAvoidDrift = 60 * Time::kMillisecondsPerSecond; 81 const int kMaxMillisecondsToAvoidDrift = 60 * Time::kMillisecondsPerSecond;
82 82
83 int64 initial_time = 0; 83 int64 initial_time = 0;
84 TimeTicks initial_ticks; 84 TimeTicks initial_ticks;
85 85
86 void InitializeClock() { 86 void InitializeClock() {
87 initial_ticks = TimeTicks::Now(); 87 initial_ticks = TimeTicks::Now();
88 initial_time = CurrentWallclockMicroseconds(); 88 initial_time = CurrentWallclockMicroseconds();
89 } 89 }
90 90
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 = base::SystemMonitor::Get();
108 DCHECK(system);
109 system->AddObserver(this);
110 UseHiResClock(!system->BatteryPower());
111 }
112
113 void StopMonitoring() {
114 if (!is_monitoring_)
115 return;
116 is_monitoring_ = false;
117 base::SystemMonitor* monitor = base::SystemMonitor::Get();
118 if (monitor)
119 monitor->RemoveObserver(this);
120 }
121
122 // Interfaces for monitoring Power changes.
123 void OnPowerStateChange(base::SystemMonitor* system) {
124 UseHiResClock(!system->BatteryPower());
125 }
126
127 void OnSuspend(base::SystemMonitor* system) {}
128 void OnResume(base::SystemMonitor* system) {}
129
130 private:
131 HighResolutionTimerManager()
132 : is_monitoring_(false),
133 hi_res_clock_enabled_(false) {
134 }
135 friend struct DefaultSingletonTraits<HighResolutionTimerManager>;
136
137 // Enable or disable the faster multimedia timer.
138 void UseHiResClock(bool enabled) {
139 if (enabled == hi_res_clock_enabled_)
140 return;
141 if (enabled)
142 timeBeginPeriod(1);
143 else
144 timeEndPeriod(1);
145 hi_res_clock_enabled_ = enabled;
146 }
147
148 bool is_monitoring_;
149 bool hi_res_clock_enabled_;
150
151 DISALLOW_COPY_AND_ASSIGN(HighResolutionTimerManager);
152 };
153
91 } // namespace 154 } // namespace
92 155
93 // Time ----------------------------------------------------------------------- 156 // Time -----------------------------------------------------------------------
94 157
95 // The internal representation of Time uses FILETIME, whose epoch is 1601-01-01 158 // The internal representation of Time uses FILETIME, whose epoch is 1601-01-01
96 // 00:00:00 UTC. ((1970-1601)*365+89)*24*60*60*1000*1000, where 89 is the 159 // 00:00:00 UTC. ((1970-1601)*365+89)*24*60*60*1000*1000, where 89 is the
97 // number of leap year days between 1601 and 1970: (1970-1601)/4 excluding 160 // number of leap year days between 1601 and 1970: (1970-1601)/4 excluding
98 // 1700, 1800, and 1900. 161 // 1700, 1800, and 1900.
99 // static 162 // static
100 const int64 Time::kTimeTToMicrosecondsOffset = GG_INT64_C(11644473600000000); 163 const int64 Time::kTimeTToMicrosecondsOffset = GG_INT64_C(11644473600000000);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 return Time(FileTimeToMicroseconds(ft)); 205 return Time(FileTimeToMicroseconds(ft));
143 } 206 }
144 207
145 FILETIME Time::ToFileTime() const { 208 FILETIME Time::ToFileTime() const {
146 FILETIME utc_ft; 209 FILETIME utc_ft;
147 MicrosecondsToFileTime(us_, &utc_ft); 210 MicrosecondsToFileTime(us_, &utc_ft);
148 return utc_ft; 211 return utc_ft;
149 } 212 }
150 213
151 // static 214 // static
215 void Time::StartSystemMonitorObserver() {
216 Singleton<HighResolutionTimerManager>()->StartMonitoring();
217 }
218
219 // static
220 void Time::EnableHiResClockForTests() {
221 Singleton<HighResolutionTimerManager>()->Enable();
222 }
223
224 // static
152 Time Time::FromExploded(bool is_local, const Exploded& exploded) { 225 Time Time::FromExploded(bool is_local, const Exploded& exploded) {
153 // Create the system struct representing our exploded time. It will either be 226 // Create the system struct representing our exploded time. It will either be
154 // in local time or UTC. 227 // in local time or UTC.
155 SYSTEMTIME st; 228 SYSTEMTIME st;
156 st.wYear = exploded.year; 229 st.wYear = exploded.year;
157 st.wMonth = exploded.month; 230 st.wMonth = exploded.month;
158 st.wDayOfWeek = exploded.day_of_week; 231 st.wDayOfWeek = exploded.day_of_week;
159 st.wDay = exploded.day_of_month; 232 st.wDay = exploded.day_of_month;
160 st.wHour = exploded.hour; 233 st.wHour = exploded.hour;
161 st.wMinute = exploded.minute; 234 st.wMinute = exploded.minute;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 } 293 }
221 294
222 295
223 DWORD (*tick_function)(void) = &timeGetTimeWrapper; 296 DWORD (*tick_function)(void) = &timeGetTimeWrapper;
224 297
225 // We use timeGetTime() to implement TimeTicks::Now(). This can be problematic 298 // We use timeGetTime() to implement TimeTicks::Now(). This can be problematic
226 // because it returns the number of milliseconds since Windows has started, 299 // because it returns the number of milliseconds since Windows has started,
227 // which will roll over the 32-bit value every ~49 days. We try to track 300 // which will roll over the 32-bit value every ~49 days. We try to track
228 // rollover ourselves, which works if TimeTicks::Now() is called at least every 301 // rollover ourselves, which works if TimeTicks::Now() is called at least every
229 // 49 days. 302 // 49 days.
230 class NowSingleton : public base::SystemMonitor::PowerObserver { 303 class NowSingleton {
231 public: 304 public:
232 NowSingleton() 305 NowSingleton()
233 : rollover_(TimeDelta::FromMilliseconds(0)), 306 : rollover_(TimeDelta::FromMilliseconds(0)),
234 last_seen_(0), 307 last_seen_(0) {
235 hi_res_clock_enabled_(false) {
236 base::SystemMonitor* system = base::SystemMonitor::Get();
237 system->AddObserver(this);
238 UseHiResClock(!system->BatteryPower());
239 } 308 }
240 309
241 ~NowSingleton() { 310 ~NowSingleton() {
242 UseHiResClock(false);
243 base::SystemMonitor* monitor = base::SystemMonitor::Get();
244 if (monitor)
245 monitor->RemoveObserver(this);
246 } 311 }
247 312
248 TimeDelta Now() { 313 TimeDelta Now() {
249 AutoLock locked(lock_); 314 AutoLock locked(lock_);
250 // We should hold the lock while calling tick_function to make sure that 315 // We should hold the lock while calling tick_function to make sure that
251 // we keep our last_seen_ stay correctly in sync. 316 // we keep our last_seen_ stay correctly in sync.
252 DWORD now = tick_function(); 317 DWORD now = tick_function();
253 if (now < last_seen_) 318 if (now < last_seen_)
254 rollover_ += TimeDelta::FromMilliseconds(0x100000000I64); // ~49.7 days. 319 rollover_ += TimeDelta::FromMilliseconds(0x100000000I64); // ~49.7 days.
255 last_seen_ = now; 320 last_seen_ = now;
256 return TimeDelta::FromMilliseconds(now) + rollover_; 321 return TimeDelta::FromMilliseconds(now) + rollover_;
257 } 322 }
258 323
259 // Interfaces for monitoring Power changes.
260 void OnPowerStateChange(base::SystemMonitor* system) {
261 UseHiResClock(!system->BatteryPower());
262 }
263
264 void OnSuspend(base::SystemMonitor* system) {}
265 void OnResume(base::SystemMonitor* system) {}
266
267 private: 324 private:
268 // Enable or disable the faster multimedia timer.
269 void UseHiResClock(bool enabled) {
270 if (enabled == hi_res_clock_enabled_)
271 return;
272 if (enabled)
273 timeBeginPeriod(1);
274 else
275 timeEndPeriod(1);
276 hi_res_clock_enabled_ = enabled;
277 }
278
279 Lock lock_; // To protected last_seen_ and rollover_. 325 Lock lock_; // To protected last_seen_ and rollover_.
280 TimeDelta rollover_; // Accumulation of time lost due to rollover. 326 TimeDelta rollover_; // Accumulation of time lost due to rollover.
281 DWORD last_seen_; // The last timeGetTime value we saw, to detect rollover. 327 DWORD last_seen_; // The last timeGetTime value we saw, to detect rollover.
282 bool hi_res_clock_enabled_;
283 328
284 DISALLOW_COPY_AND_ASSIGN(NowSingleton); 329 DISALLOW_COPY_AND_ASSIGN(NowSingleton);
285 }; 330 };
286 331
287 // Overview of time counters: 332 // Overview of time counters:
288 // (1) CPU cycle counter. (Retrieved via RDTSC) 333 // (1) CPU cycle counter. (Retrieved via RDTSC)
289 // The CPU counter provides the highest resolution time stamp and is the least 334 // The CPU counter provides the highest resolution time stamp and is the least
290 // expensive to retrieve. However, the CPU counter is unreliable and should not 335 // expensive to retrieve. However, the CPU counter is unreliable and should not
291 // be used in production. Its biggest issue is that it is per processor and it 336 // be used in production. Its biggest issue is that it is per processor and it
292 // is not synchronized between processors. Also, on some computers, the counters 337 // is not synchronized between processors. Also, on some computers, the counters
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 440
396 // static 441 // static
397 TimeTicks TimeTicks::Now() { 442 TimeTicks TimeTicks::Now() {
398 return TimeTicks() + Singleton<NowSingleton>::get()->Now(); 443 return TimeTicks() + Singleton<NowSingleton>::get()->Now();
399 } 444 }
400 445
401 // static 446 // static
402 TimeTicks TimeTicks::HighResNow() { 447 TimeTicks TimeTicks::HighResNow() {
403 return TimeTicks() + Singleton<HighResNowSingleton>::get()->Now(); 448 return TimeTicks() + Singleton<HighResNowSingleton>::get()->Now();
404 } 449 }
OLDNEW
« base/test_suite.h ('K') | « base/time.h ('k') | chrome/browser/browser_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698