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 |