Chromium Code Reviews| Index: chrome/browser/metrics/time_ticks_experiment_win.cc |
| diff --git a/chrome/browser/metrics/time_ticks_experiment_win.cc b/chrome/browser/metrics/time_ticks_experiment_win.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..df99dcb5ba329afce3dfc1593b5113d622a23e32 |
| --- /dev/null |
| +++ b/chrome/browser/metrics/time_ticks_experiment_win.cc |
| @@ -0,0 +1,108 @@ |
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/metrics/time_ticks_experiment_win.h" |
| + |
| +#if defined(OS_WIN) |
| + |
| +#include "base/cpu.h" |
| +#include "base/metrics/histogram.h" |
| +#include "base/win/windows_version.h" |
| + |
| +#include <windows.h> |
| + |
| +namespace chrome_browser_metrics { |
| + |
| +namespace { |
| + |
| +const int kNumIterations = 1000; |
| + |
| +} // anonymous namespace |
| + |
| +void CollectTimeTicksStats() { |
| + // This bit is supposed to indicate that rdtsc is safe across cores. If so, we |
| + // can use QPC as long as it uses rdtsc. |
| + // TODO(simonjam): We should look for other signals that QPC might be safe and |
| + // test them out here. |
| + base::CPU cpu; |
| + UMA_HISTOGRAM_BOOLEAN("WinTimeTicks.NonStopTsc", |
| + cpu.has_non_stop_time_stamp_counter()); |
| + if (!cpu.has_non_stop_time_stamp_counter()) { |
| + return; |
| + } |
| + |
| + DWORD default_mask; |
| + DWORD system_mask; |
| + if (!GetProcessAffinityMask(GetCurrentProcess(), |
| + &default_mask, &system_mask)) { |
| + return; |
| + } |
| + |
| + SYSTEM_INFO sys_info; |
| + GetSystemInfo(&sys_info); |
| + DWORD num_cores = sys_info.dwNumberOfProcessors; |
| + DWORD current_core = 0; |
| + bool failed_to_change_cores = false; |
| + |
| + base::win::OSInfo* info = base::win::OSInfo::GetInstance(); |
| + UMA_HISTOGRAM_ENUMERATION("WinTimeTicks.VersionTotal", info->version(), |
| + base::win::VERSION_WIN_LAST); |
| + |
| + LARGE_INTEGER qpc_frequency; |
| + QueryPerformanceFrequency(&qpc_frequency); |
| + |
| + int min_delta = 1e9; |
| + LARGE_INTEGER qpc_last; |
| + QueryPerformanceCounter(&qpc_last); |
| + for (int i = 0; i < kNumIterations; ++i) { |
| + LARGE_INTEGER qpc_now; |
| + QueryPerformanceCounter(&qpc_now); |
| + int delta = static_cast<int>(qpc_now.QuadPart - qpc_last.QuadPart); |
| + if (delta != 0) { |
| + min_delta = std::min(min_delta, delta); |
| + } |
| + qpc_last = qpc_now; |
| + |
| + if (num_cores > 1 && (i % 100) == 0) { |
| + ++current_core; |
| + if (current_core > num_cores) { |
| + current_core = 0; |
| + } |
| + if (!SetThreadAffinityMask(GetCurrentThread(), 1 << current_core)) { |
| + failed_to_change_cores = true; |
| + break; |
| + } |
| + } |
| + } |
| + |
| + if (num_cores > 1) { |
| + SetThreadAffinityMask(GetCurrentThread(), default_mask); |
|
Sigurður Ásgeirsson
2013/04/19 12:59:17
ah - great catch :)
|
| + if (failed_to_change_cores) { |
| + UMA_HISTOGRAM_ENUMERATION("WinTimeTicks.FailedToChangeCores", |
| + info->version(), base::win::VERSION_WIN_LAST); |
| + return; |
| + } |
| + } |
| + |
| + if (min_delta < 0) { |
| + UMA_HISTOGRAM_ENUMERATION("WinTimeTicks.TickedBackwards", info->version(), |
| + base::win::VERSION_WIN_LAST); |
| + return; |
| + } |
| + |
| + int min_delta_ns = static_cast<int>( |
| + min_delta * (1e9 / qpc_frequency.QuadPart)); |
| + UMA_HISTOGRAM_CUSTOM_COUNTS("WinTimeTicks.MinResolutionNanoseconds", |
| + min_delta_ns, 1, 1000000, 50); |
| + |
| + bool success = min_delta_ns <= 10000; |
| + if (success) { |
| + UMA_HISTOGRAM_ENUMERATION("WinTimeTicks.VersionSuccessful", |
| + info->version(), base::win::VERSION_WIN_LAST); |
| + } |
| +} |
| + |
| +} // namespace chrome_browser_net |
| + |
| +#endif // defined(OS_WIN) |