Chromium Code Reviews| 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 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 429 | 429 |
| 430 void InitializeNowFunctionPointers() { | 430 void InitializeNowFunctionPointers() { |
| 431 LARGE_INTEGER ticks_per_sec = {}; | 431 LARGE_INTEGER ticks_per_sec = {}; |
| 432 if (!QueryPerformanceFrequency(&ticks_per_sec)) | 432 if (!QueryPerformanceFrequency(&ticks_per_sec)) |
| 433 ticks_per_sec.QuadPart = 0; | 433 ticks_per_sec.QuadPart = 0; |
| 434 | 434 |
| 435 // If Windows cannot provide a QPC implementation, both TimeTicks::Now() and | 435 // If Windows cannot provide a QPC implementation, both TimeTicks::Now() and |
| 436 // TraceTicks::Now() must use the low-resolution clock. | 436 // TraceTicks::Now() must use the low-resolution clock. |
| 437 // | 437 // |
| 438 // If the QPC implementation is expensive and/or unreliable, TimeTicks::Now() | 438 // If the QPC implementation is expensive and/or unreliable, TimeTicks::Now() |
| 439 // will use the low-resolution clock, but TraceTicks::Now() will use the QPC | 439 // and TraceTicks::Now() will still use the low-resolution clock. A CPU |
| 440 // (in the hope that it is still useful for tracing purposes). A CPU lacking a | 440 // lacking a non-stop time counter will cause Windows to provide an alternate |
| 441 // non-stop time counter will cause Windows to provide an alternate QPC | 441 // QPC implementation that works, but is expensive to use. Certain Athlon CPUs |
| 442 // implementation that works, but is expensive to use. Certain Athlon CPUs are | 442 // are known to make the QPC implementation unreliable. |
| 443 // known to make the QPC implementation unreliable. | |
| 444 // | 443 // |
| 445 // Otherwise, both Now functions can use the high-resolution QPC clock. As of | 444 // Otherwise, both Now functions can use the high-resolution QPC clock. As of |
| 446 // 4 January 2015, ~68% of users fall within this category. | 445 // 21 August 2015, ~72% of users fall within this category. |
| 447 NowFunction now_function; | 446 NowFunction now_function; |
| 448 NowFunction system_trace_now_function; | 447 NowFunction system_trace_now_function; |
| 449 base::CPU cpu; | 448 base::CPU cpu; |
| 450 if (ticks_per_sec.QuadPart <= 0) { | 449 if (ticks_per_sec.QuadPart <= 0 || |
| 450 !cpu.has_non_stop_time_stamp_counter() || IsBuggyAthlon(cpu)) { | |
| 451 now_function = system_trace_now_function = &RolloverProtectedNow; | 451 now_function = system_trace_now_function = &RolloverProtectedNow; |
|
fmeawad
2015/08/21 21:24:40
Can you explain why you still need 2 variable (now
| |
| 452 } else if (!cpu.has_non_stop_time_stamp_counter() || IsBuggyAthlon(cpu)) { | |
| 453 now_function = &RolloverProtectedNow; | |
| 454 system_trace_now_function = &QPCNow; | |
| 455 } else { | 452 } else { |
| 456 now_function = system_trace_now_function = &QPCNow; | 453 now_function = system_trace_now_function = &QPCNow; |
| 457 } | 454 } |
| 458 | 455 |
| 459 // Threading note 1: In an unlikely race condition, it's possible for two or | 456 // Threading note 1: In an unlikely race condition, it's possible for two or |
| 460 // more threads to enter InitializeNowFunctionPointers() in parallel. This is | 457 // more threads to enter InitializeNowFunctionPointers() in parallel. This is |
| 461 // not a problem since all threads should end up writing out the same values | 458 // not a problem since all threads should end up writing out the same values |
| 462 // to the global variables. | 459 // to the global variables. |
| 463 // | 460 // |
| 464 // Threading note 2: A release fence is placed here to ensure, from the | 461 // Threading note 2: A release fence is placed here to ensure, from the |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 521 TimeTicks TimeTicks::FromQPCValue(LONGLONG qpc_value) { | 518 TimeTicks TimeTicks::FromQPCValue(LONGLONG qpc_value) { |
| 522 return TimeTicks() + QPCValueToTimeDelta(qpc_value); | 519 return TimeTicks() + QPCValueToTimeDelta(qpc_value); |
| 523 } | 520 } |
| 524 | 521 |
| 525 // TimeDelta ------------------------------------------------------------------ | 522 // TimeDelta ------------------------------------------------------------------ |
| 526 | 523 |
| 527 // static | 524 // static |
| 528 TimeDelta TimeDelta::FromQPCValue(LONGLONG qpc_value) { | 525 TimeDelta TimeDelta::FromQPCValue(LONGLONG qpc_value) { |
| 529 return QPCValueToTimeDelta(qpc_value); | 526 return QPCValueToTimeDelta(qpc_value); |
| 530 } | 527 } |
| OLD | NEW |