| Index: base/time/time_win.cc
|
| diff --git a/base/time/time_win.cc b/base/time/time_win.cc
|
| index e9044603e9aedf7a7841d6f2e8406ad68289f291..ff1d955be8232bb44f24f2494e867f7632304911 100644
|
| --- a/base/time/time_win.cc
|
| +++ b/base/time/time_win.cc
|
| @@ -382,10 +382,9 @@ using NowFunction = TimeDelta (*)(void);
|
| TimeDelta InitialNowFunction();
|
| TimeDelta InitialSystemTraceNowFunction();
|
|
|
| -// See "threading notes" in InitializeNowFunctionPointers() for details on how
|
| +// See "threading notes" in InitializeNowFunctionPointer() for details on how
|
| // concurrent reads/writes to these globals has been made safe.
|
| NowFunction g_now_function = &InitialNowFunction;
|
| -NowFunction g_system_trace_now_function = &InitialSystemTraceNowFunction;
|
| int64 g_qpc_ticks_per_second = 0;
|
|
|
| // As of January 2015, use of <atomic> is forbidden in Chromium code. This is
|
| @@ -395,7 +394,7 @@ int64 g_qpc_ticks_per_second = 0;
|
|
|
| TimeDelta QPCValueToTimeDelta(LONGLONG qpc_value) {
|
| // Ensure that the assignment to |g_qpc_ticks_per_second|, made in
|
| - // InitializeNowFunctionPointers(), has happened by this point.
|
| + // InitializeNowFunctionPointer(), has happened by this point.
|
| ATOMIC_THREAD_FENCE(memory_order_acquire);
|
|
|
| DCHECK_GT(g_qpc_ticks_per_second, 0);
|
| @@ -427,37 +426,41 @@ bool IsBuggyAthlon(const base::CPU& cpu) {
|
| return cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15;
|
| }
|
|
|
| -void InitializeNowFunctionPointers() {
|
| +void InitializeNowFunctionPointer() {
|
| LARGE_INTEGER ticks_per_sec = {};
|
| if (!QueryPerformanceFrequency(&ticks_per_sec))
|
| ticks_per_sec.QuadPart = 0;
|
|
|
| - // If Windows cannot provide a QPC implementation, both TimeTicks::Now() and
|
| - // TraceTicks::Now() must use the low-resolution clock.
|
| + // If Windows cannot provide a QPC implementation, TimeTicks::Now() must use
|
| + // the low-resolution clock.
|
| //
|
| // If the QPC implementation is expensive and/or unreliable, TimeTicks::Now()
|
| - // will use the low-resolution clock, but TraceTicks::Now() will use the QPC
|
| - // (in the hope that it is still useful for tracing purposes). A CPU lacking a
|
| - // non-stop time counter will cause Windows to provide an alternate QPC
|
| - // implementation that works, but is expensive to use. Certain Athlon CPUs are
|
| - // known to make the QPC implementation unreliable.
|
| + // will still use the low-resolution clock. A CPU lacking a non-stop time
|
| + // counter will cause Windows to provide an alternate QPC implementation that
|
| + // works, but is expensive to use. Certain Athlon CPUs are known to make the
|
| + // QPC implementation unreliable.
|
| //
|
| - // Otherwise, both Now functions can use the high-resolution QPC clock. As of
|
| - // 4 January 2015, ~68% of users fall within this category.
|
| + // Otherwise, Now uses the high-resolution QPC clock. As of 21 August 2015,
|
| + // ~72% of users fall within this category.
|
| + //
|
| + // TraceTicks::Now() always uses the same clock as TimeTicks::Now(), even
|
| + // when the QPC exists but is expensive or unreliable. This is because we'd
|
| + // eventually like to merge TraceTicks and TimeTicks and have one type of
|
| + // timestamp that is reliable, monotonic, and comparable. Also, while we could
|
| + // use the high-resolution timer for TraceTicks even when it's unreliable or
|
| + // slow, it's easier to make tracing tools accommodate a coarse timer than
|
| + // one that's unreliable or slow.
|
| NowFunction now_function;
|
| - NowFunction system_trace_now_function;
|
| base::CPU cpu;
|
| - if (ticks_per_sec.QuadPart <= 0) {
|
| - now_function = system_trace_now_function = &RolloverProtectedNow;
|
| - } else if (!cpu.has_non_stop_time_stamp_counter() || IsBuggyAthlon(cpu)) {
|
| + if (ticks_per_sec.QuadPart <= 0 ||
|
| + !cpu.has_non_stop_time_stamp_counter() || IsBuggyAthlon(cpu)) {
|
| now_function = &RolloverProtectedNow;
|
| - system_trace_now_function = &QPCNow;
|
| } else {
|
| - now_function = system_trace_now_function = &QPCNow;
|
| + now_function = &QPCNow;
|
| }
|
|
|
| // Threading note 1: In an unlikely race condition, it's possible for two or
|
| - // more threads to enter InitializeNowFunctionPointers() in parallel. This is
|
| + // more threads to enter InitializeNowFunctionPointer() in parallel. This is
|
| // not a problem since all threads should end up writing out the same values
|
| // to the global variables.
|
| //
|
| @@ -468,19 +471,13 @@ void InitializeNowFunctionPointers() {
|
| g_qpc_ticks_per_second = ticks_per_sec.QuadPart;
|
| ATOMIC_THREAD_FENCE(memory_order_release);
|
| g_now_function = now_function;
|
| - g_system_trace_now_function = system_trace_now_function;
|
| }
|
|
|
| TimeDelta InitialNowFunction() {
|
| - InitializeNowFunctionPointers();
|
| + InitializeNowFunctionPointer();
|
| return g_now_function();
|
| }
|
|
|
| -TimeDelta InitialSystemTraceNowFunction() {
|
| - InitializeNowFunctionPointers();
|
| - return g_system_trace_now_function();
|
| -}
|
| -
|
| } // namespace
|
|
|
| // static
|
| @@ -502,7 +499,7 @@ TimeTicks TimeTicks::Now() {
|
| // static
|
| bool TimeTicks::IsHighResolution() {
|
| if (g_now_function == &InitialNowFunction)
|
| - InitializeNowFunctionPointers();
|
| + InitializeNowFunctionPointer();
|
| return g_now_function == &QPCNow;
|
| }
|
|
|
| @@ -514,7 +511,7 @@ ThreadTicks ThreadTicks::Now() {
|
|
|
| // static
|
| TraceTicks TraceTicks::Now() {
|
| - return TraceTicks() + g_system_trace_now_function();
|
| + return TraceTicks() + g_now_function();
|
| }
|
|
|
| // static
|
|
|