OLD | NEW |
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 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 TimeDelta FromQPCValue(LONGLONG qpcValue) { |
| 375 return TimeDelta::FromMicroseconds( |
| 376 static_cast<int64>(qpcValue / ticks_per_microsecond_)); |
| 377 } |
| 378 |
374 private: | 379 private: |
375 HighResNowSingleton() | 380 HighResNowSingleton() |
376 : ticks_per_microsecond_(0.0), | 381 : ticks_per_microsecond_(0.0), |
377 skew_(0) { | 382 skew_(0) { |
378 InitializeClock(); | 383 InitializeClock(); |
379 | 384 |
380 // On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is | 385 // On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is |
381 // unreliable. Fallback to low-res clock. | 386 // unreliable. Fallback to low-res clock. |
382 base::CPU cpu; | 387 base::CPU cpu; |
383 if (cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15) | 388 if (cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15) |
384 DisableHighResClock(); | 389 DisableHighResClock(); |
385 } | 390 } |
386 | 391 |
387 // Synchronize the QPC clock with GetSystemTimeAsFileTime. | 392 // Synchronize the QPC clock with GetSystemTimeAsFileTime. |
388 void InitializeClock() { | 393 void InitializeClock() { |
389 LARGE_INTEGER ticks_per_sec = {0}; | 394 LARGE_INTEGER ticks_per_sec = {0}; |
390 if (!QueryPerformanceFrequency(&ticks_per_sec)) | 395 if (!QueryPerformanceFrequency(&ticks_per_sec)) |
391 return; // Broken, we don't guarantee this function works. | 396 return; // Broken, we don't guarantee this function works. |
392 ticks_per_microsecond_ = static_cast<float>(ticks_per_sec.QuadPart) / | 397 ticks_per_microsecond_ = static_cast<double>(ticks_per_sec.QuadPart) / |
393 static_cast<float>(Time::kMicrosecondsPerSecond); | 398 static_cast<double>(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 static_cast<int64>(now.QuadPart / ticks_per_microsecond_); |
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 |
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 double ticks_per_microsecond_; // 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 Loading... |
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 qpcValue) { |
| 455 return TimeTicks() + |
| 456 HighResNowSingleton::GetInstance()->FromQPCValue(qpcValue); |
| 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 qpcValue) { |
| 468 return HighResNowSingleton::GetInstance()->FromQPCValue(qpcValue); |
| 469 } |
OLD | NEW |