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

Side by Side Diff: base/time_win.cc

Issue 10843038: Add native QPC to base::Time* conversion on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Replace all instances of ticks_per_millisecond Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « base/time.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 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 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 // (3) System time. The system time provides a low-resolution (typically 10ms 337 // (3) System time. The system time provides a low-resolution (typically 10ms
338 // to 55 milliseconds) time stamp but is comparatively less expensive to 338 // to 55 milliseconds) time stamp but is comparatively less expensive to
339 // retrieve and more reliable. 339 // retrieve and more reliable.
340 class HighResNowSingleton { 340 class HighResNowSingleton {
341 public: 341 public:
342 static HighResNowSingleton* GetInstance() { 342 static HighResNowSingleton* GetInstance() {
343 return Singleton<HighResNowSingleton>::get(); 343 return Singleton<HighResNowSingleton>::get();
344 } 344 }
345 345
346 bool IsUsingHighResClock() { 346 bool IsUsingHighResClock() {
347 return ticks_per_microsecond_ != 0.0; 347 return ticks_per_second_ != 0.0;
348 } 348 }
349 349
350 void DisableHighResClock() { 350 void DisableHighResClock() {
351 ticks_per_microsecond_ = 0.0; 351 ticks_per_second_ = 0.0;
352 } 352 }
353 353
354 TimeDelta Now() { 354 TimeDelta Now() {
355 if (IsUsingHighResClock()) 355 if (IsUsingHighResClock())
356 return TimeDelta::FromMicroseconds(UnreliableNow()); 356 return TimeDelta::FromMicroseconds(UnreliableNow());
357 357
358 // Just fallback to the slower clock. 358 // Just fallback to the slower clock.
359 return RolloverProtectedNow(); 359 return RolloverProtectedNow();
360 } 360 }
361 361
362 int64 GetQPCDriftMicroseconds() { 362 int64 GetQPCDriftMicroseconds() {
363 if (!IsUsingHighResClock()) 363 if (!IsUsingHighResClock())
364 return 0; 364 return 0;
365 365
366 // The static_cast<long> is needed as a hint to VS 2008 to tell it 366 // The static_cast<long> is needed as a hint to VS 2008 to tell it
367 // which version of abs() to use. Other compilers don't seem to 367 // which version of abs() to use. Other compilers don't seem to
368 // need it, including VS 2010, but to keep code identical we use it 368 // need it, including VS 2010, but to keep code identical we use it
369 // everywhere. 369 // everywhere.
370 // TODO(joi): Remove the hint if/when we no longer support VS 2008. 370 // TODO(joi): Remove the hint if/when we no longer support VS 2008.
371 return abs(static_cast<long>((UnreliableNow() - ReliableNow()) - skew_)); 371 return abs(static_cast<long>((UnreliableNow() - ReliableNow()) - skew_));
372 } 372 }
373 373
374 int64 QPCValueToMicroseconds(LONGLONG qpc_value) {
375 if (ticks_per_second_)
376 return qpc_value * Time::kMicrosecondsPerSecond / ticks_per_second_;
jar (doing other things) 2012/08/02 03:13:20 nit: 2 character indent from start of "if"
377 return 0;
378 }
379
374 private: 380 private:
375 HighResNowSingleton() 381 HighResNowSingleton()
376 : ticks_per_microsecond_(0.0), 382 : ticks_per_second_(0),
jbates 2012/08/02 03:10:34 what's the reason for changing to per_second? seem
brianderson 2012/08/02 19:04:14 Using ticks per second, we are dividing by the act
377 skew_(0) { 383 skew_(0) {
378 InitializeClock(); 384 InitializeClock();
379 385
380 // On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is 386 // On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is
381 // unreliable. Fallback to low-res clock. 387 // unreliable. Fallback to low-res clock.
382 base::CPU cpu; 388 base::CPU cpu;
383 if (cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15) 389 if (cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15)
384 DisableHighResClock(); 390 DisableHighResClock();
385 } 391 }
386 392
387 // Synchronize the QPC clock with GetSystemTimeAsFileTime. 393 // Synchronize the QPC clock with GetSystemTimeAsFileTime.
388 void InitializeClock() { 394 void InitializeClock() {
389 LARGE_INTEGER ticks_per_sec = {0}; 395 LARGE_INTEGER ticks_per_sec = {0};
390 if (!QueryPerformanceFrequency(&ticks_per_sec)) 396 if (!QueryPerformanceFrequency(&ticks_per_sec))
391 return; // Broken, we don't guarantee this function works. 397 return; // Broken, we don't guarantee this function works.
392 ticks_per_microsecond_ = static_cast<float>(ticks_per_sec.QuadPart) / 398 ticks_per_second_ = ticks_per_sec.QuadPart;
393 static_cast<float>(Time::kMicrosecondsPerSecond);
394 399
395 skew_ = UnreliableNow() - ReliableNow(); 400 skew_ = UnreliableNow() - ReliableNow();
396 } 401 }
397 402
398 // Get the number of microseconds since boot in an unreliable fashion. 403 // Get the number of microseconds since boot in an unreliable fashion.
399 int64 UnreliableNow() { 404 int64 UnreliableNow() {
400 LARGE_INTEGER now; 405 LARGE_INTEGER now;
401 QueryPerformanceCounter(&now); 406 QueryPerformanceCounter(&now);
402 return static_cast<int64>(now.QuadPart / ticks_per_microsecond_); 407 return now.QuadPart * Time::kMicrosecondsPerSecond / ticks_per_second_;
jar (doing other things) 2012/08/02 03:13:20 I think this is going to work ok (working with int
403 } 408 }
404 409
405 // Get the number of microseconds since boot in a reliable fashion. 410 // Get the number of microseconds since boot in a reliable fashion.
406 int64 ReliableNow() { 411 int64 ReliableNow() {
407 return RolloverProtectedNow().InMicroseconds(); 412 return RolloverProtectedNow().InMicroseconds();
408 } 413 }
409 414
410 // Cached clock frequency -> microseconds. This assumes that the clock 415 // Cached clock frequency -> microseconds. This assumes that the clock
jar (doing other things) 2012/08/02 03:13:20 Comment should be changed or removed.
411 // frequency is faster than one microsecond (which is 1MHz, should be OK). 416 // frequency is faster than one microsecond (which is 1MHz, should be OK).
412 float ticks_per_microsecond_; // 0 indicates QPF failed and we're broken. 417 int64 ticks_per_second_; // 0 indicates QPF failed and we're broken.
413 int64 skew_; // Skew between lo-res and hi-res clocks (for debugging). 418 int64 skew_; // Skew between lo-res and hi-res clocks (for debugging).
414 419
415 friend struct DefaultSingletonTraits<HighResNowSingleton>; 420 friend struct DefaultSingletonTraits<HighResNowSingleton>;
416 }; 421 };
417 422
418 } // namespace 423 } // namespace
419 424
420 // static 425 // static
421 TimeTicks::TickFunctionType TimeTicks::SetMockTickFunction( 426 TimeTicks::TickFunctionType TimeTicks::SetMockTickFunction(
422 TickFunctionType ticker) { 427 TickFunctionType ticker) {
(...skipping 16 matching lines...) Expand all
439 TimeTicks TimeTicks::NowFromSystemTraceTime() { 444 TimeTicks TimeTicks::NowFromSystemTraceTime() {
440 return HighResNow(); 445 return HighResNow();
441 } 446 }
442 447
443 // static 448 // static
444 int64 TimeTicks::GetQPCDriftMicroseconds() { 449 int64 TimeTicks::GetQPCDriftMicroseconds() {
445 return HighResNowSingleton::GetInstance()->GetQPCDriftMicroseconds(); 450 return HighResNowSingleton::GetInstance()->GetQPCDriftMicroseconds();
446 } 451 }
447 452
448 // static 453 // static
454 TimeTicks TimeTicks::FromQPCValue(LONGLONG qpc_value) {
455 return TimeTicks(
456 HighResNowSingleton::GetInstance()->QPCValueToMicroseconds(qpc_value));
457 }
458
459 // static
449 bool TimeTicks::IsHighResClockWorking() { 460 bool TimeTicks::IsHighResClockWorking() {
450 return HighResNowSingleton::GetInstance()->IsUsingHighResClock(); 461 return HighResNowSingleton::GetInstance()->IsUsingHighResClock();
451 } 462 }
463
464 // TimeDelta ------------------------------------------------------------------
465
466 // static
467 TimeDelta TimeDelta::FromQPCValue(LONGLONG qpc_value) {
468 return TimeDelta(
469 HighResNowSingleton::GetInstance()->QPCValueToMicroseconds(qpc_value));
470 }
OLDNEW
« no previous file with comments | « base/time.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698