| Index: base/time/time_win.cc
|
| diff --git a/base/time/time_win.cc b/base/time/time_win.cc
|
| index 3680ee2a5e72478499a1079ac69af811d0a45c52..f35f735bfbd053196899d560b51110b2c3e2b76a 100644
|
| --- a/base/time/time_win.cc
|
| +++ b/base/time/time_win.cc
|
| @@ -322,6 +322,12 @@ TimeDelta RolloverProtectedNow() {
|
| return TimeDelta::FromMilliseconds(now + rollover_ms);
|
| }
|
|
|
| +bool IsBuggyAthlon(const base::CPU& cpu) {
|
| + // On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is
|
| + // unreliable. Fallback to low-res clock.
|
| + return cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15;
|
| +}
|
| +
|
| // Overview of time counters:
|
| // (1) CPU cycle counter. (Retrieved via RDTSC)
|
| // The CPU counter provides the highest resolution time stamp and is the least
|
| @@ -398,10 +404,8 @@ class HighResNowSingleton {
|
| skew_(0) {
|
| InitializeClock();
|
|
|
| - // On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is
|
| - // unreliable. Fallback to low-res clock.
|
| base::CPU cpu;
|
| - if (cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15)
|
| + if (IsBuggyAthlon(cpu))
|
| DisableHighResClock();
|
| }
|
|
|
| @@ -433,6 +437,24 @@ class HighResNowSingleton {
|
| friend struct DefaultSingletonTraits<HighResNowSingleton>;
|
| };
|
|
|
| +TimeDelta HighResNowWrapper() {
|
| + return HighResNowSingleton::GetInstance()->Now();
|
| +}
|
| +
|
| +typedef TimeDelta (*NowFunction)(void);
|
| +NowFunction now_function = RolloverProtectedNow;
|
| +
|
| +bool CPUReliablySupportsHighResTime() {
|
| + base::CPU cpu;
|
| + if (!cpu.has_non_stop_time_stamp_counter())
|
| + return false;
|
| +
|
| + if (IsBuggyAthlon(cpu))
|
| + return false;
|
| +
|
| + return true;
|
| +}
|
| +
|
| } // namespace
|
|
|
| // static
|
| @@ -447,8 +469,18 @@ TimeTicks::TickFunctionType TimeTicks::SetMockTickFunction(
|
| }
|
|
|
| // static
|
| +bool TimeTicks::SetNowIsHighResNowIfSupported() {
|
| + if (!CPUReliablySupportsHighResTime()) {
|
| + return false;
|
| + }
|
| +
|
| + now_function = HighResNowWrapper;
|
| + return true;
|
| +}
|
| +
|
| +// static
|
| TimeTicks TimeTicks::Now() {
|
| - return TimeTicks() + RolloverProtectedNow();
|
| + return TimeTicks() + now_function();
|
| }
|
|
|
| // static
|
| @@ -483,6 +515,14 @@ bool TimeTicks::IsHighResClockWorking() {
|
| return HighResNowSingleton::GetInstance()->IsUsingHighResClock();
|
| }
|
|
|
| +TimeTicks TimeTicks::UnprotectedNow() {
|
| + if (now_function == HighResNowWrapper) {
|
| + return Now();
|
| + } else {
|
| + return TimeTicks() + TimeDelta::FromMilliseconds(timeGetTime());
|
| + }
|
| +}
|
| +
|
| // TimeDelta ------------------------------------------------------------------
|
|
|
| // static
|
|
|