| 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 #include "chrome/browser/metrics/perf/perf_provider_chromeos.h" | 5 #include "chrome/browser/metrics/perf/perf_provider_chromeos.h" |
| 6 | 6 |
| 7 #include <algorithm> |
| 7 #include <string> | 8 #include <string> |
| 8 | 9 |
| 9 #include "base/bind.h" | 10 #include "base/bind.h" |
| 10 #include "base/callback.h" | 11 #include "base/callback.h" |
| 11 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 12 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 13 #include "base/rand_util.h" | 14 #include "base/rand_util.h" |
| 15 #include "base/strings/string_split.h" |
| 14 #include "base/threading/sequenced_worker_pool.h" | 16 #include "base/threading/sequenced_worker_pool.h" |
| 15 #include "chrome/browser/metrics/perf/windowed_incognito_observer.h" | 17 #include "chrome/browser/metrics/perf/windowed_incognito_observer.h" |
| 16 #include "chrome/browser/ui/browser_list.h" | 18 #include "chrome/browser/ui/browser_list.h" |
| 17 #include "chromeos/dbus/dbus_thread_manager.h" | 19 #include "chromeos/dbus/dbus_thread_manager.h" |
| 18 #include "chromeos/dbus/debug_daemon_client.h" | 20 #include "chromeos/dbus/debug_daemon_client.h" |
| 19 | 21 |
| 20 namespace metrics { | 22 namespace metrics { |
| 21 | 23 |
| 22 namespace { | 24 namespace { |
| 23 | 25 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 bool IsNormalUserLoggedIn() { | 61 bool IsNormalUserLoggedIn() { |
| 60 return chromeos::LoginState::Get()->IsUserAuthenticated(); | 62 return chromeos::LoginState::Get()->IsUserAuthenticated(); |
| 61 } | 63 } |
| 62 | 64 |
| 63 // Returns a random TimeDelta between zero and |max|. | 65 // Returns a random TimeDelta between zero and |max|. |
| 64 base::TimeDelta RandomTimeDelta(base::TimeDelta max) { | 66 base::TimeDelta RandomTimeDelta(base::TimeDelta max) { |
| 65 return base::TimeDelta::FromMicroseconds( | 67 return base::TimeDelta::FromMicroseconds( |
| 66 base::RandGenerator(max.InMicroseconds())); | 68 base::RandGenerator(max.InMicroseconds())); |
| 67 } | 69 } |
| 68 | 70 |
| 71 // Hopefully we never need a space in a command argument. |
| 72 const char kPerfCommandDelimiter[] = " "; |
| 73 |
| 74 const char kPerfRecordCyclesCmd[] = |
| 75 "perf record -a -e cycles -c 1000003"; |
| 76 |
| 77 const char kPerfRecordCallgraphCmd[] = |
| 78 "perf record -a -e cycles -g -c 4000037"; |
| 79 |
| 80 const char kPerfRecordLBRCmd[] = |
| 81 "perf record -a -e r2c4 -b -c 20011"; |
| 82 |
| 83 const char kPerfRecordInstructionTLBMissesCmd[] = |
| 84 "perf record -a -e iTLB-misses -c 2003"; |
| 85 |
| 86 const char kPerfRecordDataTLBMissesCmd[] = |
| 87 "perf record -a -e dTLB-misses -c 2003"; |
| 88 |
| 89 const char kPerfStatMemoryBandwidthCmd[] = |
| 90 "perf stat -a -e cycles -e instructions " |
| 91 "-e uncore_imc/data_reads/ -e uncore_imc/data_writes/ " |
| 92 "-e cpu/event=0xD0,umask=0x11,name=MEM_UOPS_RETIRED-STLB_MISS_LOADS/ " |
| 93 "-e cpu/event=0xD0,umask=0x12,name=MEM_UOPS_RETIRED-STLB_MISS_STORES/"; |
| 94 |
| 95 const std::vector<RandomSelector::WeightAndValue> GetDefaultCommands_x86_64( |
| 96 const CPUIdentity& cpuid) { |
| 97 using WeightAndValue = RandomSelector::WeightAndValue; |
| 98 std::vector<WeightAndValue> cmds; |
| 99 DCHECK_EQ(cpuid.arch, "x86_64"); |
| 100 const std::string intel_uarch = GetIntelUarch(cpuid); |
| 101 if (intel_uarch == "IvyBridge" || |
| 102 intel_uarch == "Haswell" || |
| 103 intel_uarch == "Broadwell") { |
| 104 cmds.push_back(WeightAndValue(60.0, kPerfRecordCyclesCmd)); |
| 105 cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); |
| 106 cmds.push_back(WeightAndValue(5.0, kPerfRecordLBRCmd)); |
| 107 cmds.push_back(WeightAndValue(5.0, kPerfRecordInstructionTLBMissesCmd)); |
| 108 cmds.push_back(WeightAndValue(5.0, kPerfRecordDataTLBMissesCmd)); |
| 109 cmds.push_back(WeightAndValue(5.0, kPerfStatMemoryBandwidthCmd)); |
| 110 return cmds; |
| 111 } |
| 112 if (intel_uarch == "SandyBridge") { |
| 113 cmds.push_back(WeightAndValue(65.0, kPerfRecordCyclesCmd)); |
| 114 cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); |
| 115 cmds.push_back(WeightAndValue(5.0, kPerfRecordLBRCmd)); |
| 116 cmds.push_back(WeightAndValue(5.0, kPerfRecordInstructionTLBMissesCmd)); |
| 117 cmds.push_back(WeightAndValue(5.0, kPerfRecordDataTLBMissesCmd)); |
| 118 return cmds; |
| 119 } |
| 120 // Other 64-bit x86 |
| 121 cmds.push_back(WeightAndValue(70.0, kPerfRecordCyclesCmd)); |
| 122 cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); |
| 123 cmds.push_back(WeightAndValue(5.0, kPerfRecordInstructionTLBMissesCmd)); |
| 124 cmds.push_back(WeightAndValue(5.0, kPerfRecordDataTLBMissesCmd)); |
| 125 return cmds; |
| 126 } |
| 127 |
| 69 } // namespace | 128 } // namespace |
| 70 | 129 |
| 130 namespace internal { |
| 131 |
| 132 std::vector<RandomSelector::WeightAndValue> GetDefaultCommandsForCpu( |
| 133 const CPUIdentity& cpuid) { |
| 134 using WeightAndValue = RandomSelector::WeightAndValue; |
| 135 |
| 136 if (cpuid.arch == "x86_64") // 64-bit x86 |
| 137 return GetDefaultCommands_x86_64(cpuid); |
| 138 |
| 139 std::vector<WeightAndValue> cmds; |
| 140 if (cpuid.arch == "x86" || // 32-bit x86, or... |
| 141 cpuid.arch == "armv7l") { // ARM |
| 142 cmds.push_back(WeightAndValue(80.0, kPerfRecordCyclesCmd)); |
| 143 cmds.push_back(WeightAndValue(20.0, kPerfRecordCallgraphCmd)); |
| 144 return cmds; |
| 145 } |
| 146 |
| 147 // Unknown CPUs |
| 148 cmds.push_back(WeightAndValue(1.0, kPerfRecordCyclesCmd)); |
| 149 return cmds; |
| 150 } |
| 151 |
| 152 } // namespace internal |
| 153 |
| 71 PerfProvider::CollectionParams::CollectionParams( | 154 PerfProvider::CollectionParams::CollectionParams( |
| 72 base::TimeDelta collection_duration, | 155 base::TimeDelta collection_duration, |
| 73 base::TimeDelta periodic_interval, | 156 base::TimeDelta periodic_interval, |
| 74 TriggerParams resume_from_suspend, | 157 TriggerParams resume_from_suspend, |
| 75 TriggerParams restore_session) | 158 TriggerParams restore_session) |
| 76 : collection_duration_(collection_duration.ToInternalValue()), | 159 : collection_duration_(collection_duration.ToInternalValue()), |
| 77 periodic_interval_(periodic_interval.ToInternalValue()), | 160 periodic_interval_(periodic_interval.ToInternalValue()), |
| 78 resume_from_suspend_(resume_from_suspend), | 161 resume_from_suspend_(resume_from_suspend), |
| 79 restore_session_(restore_session) { | 162 restore_session_(restore_session) { |
| 80 } | 163 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 94 /* max_collection_delay = */ base::TimeDelta::FromSeconds(5)), | 177 /* max_collection_delay = */ base::TimeDelta::FromSeconds(5)), |
| 95 /* restore_session = */ PerfProvider::CollectionParams::TriggerParams( | 178 /* restore_session = */ PerfProvider::CollectionParams::TriggerParams( |
| 96 /* sampling_factor = */ 10, | 179 /* sampling_factor = */ 10, |
| 97 /* max_collection_delay = */ base::TimeDelta::FromSeconds(10))); | 180 /* max_collection_delay = */ base::TimeDelta::FromSeconds(10))); |
| 98 | 181 |
| 99 PerfProvider::PerfProvider() | 182 PerfProvider::PerfProvider() |
| 100 : collection_params_(kDefaultParameters), | 183 : collection_params_(kDefaultParameters), |
| 101 login_observer_(this), | 184 login_observer_(this), |
| 102 next_profiling_interval_start_(base::TimeTicks::Now()), | 185 next_profiling_interval_start_(base::TimeTicks::Now()), |
| 103 weak_factory_(this) { | 186 weak_factory_(this) { |
| 187 command_selector_.SetOdds( |
| 188 internal::GetDefaultCommandsForCpu(GetCPUIdentity())), |
| 189 |
| 104 // Register the login observer with LoginState. | 190 // Register the login observer with LoginState. |
| 105 chromeos::LoginState::Get()->AddObserver(&login_observer_); | 191 chromeos::LoginState::Get()->AddObserver(&login_observer_); |
| 106 | 192 |
| 107 // Register as an observer of power manager events. | 193 // Register as an observer of power manager events. |
| 108 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> | 194 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> |
| 109 AddObserver(this); | 195 AddObserver(this); |
| 110 | 196 |
| 111 // Register as an observer of session restore. | 197 // Register as an observer of session restore. |
| 112 on_session_restored_callback_subscription_ = | 198 on_session_restored_callback_subscription_ = |
| 113 SessionRestore::RegisterOnSessionRestoredCallback( | 199 SessionRestore::RegisterOnSessionRestoredCallback( |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 AddToPerfHistogram(INCOGNITO_ACTIVE); | 419 AddToPerfHistogram(INCOGNITO_ACTIVE); |
| 334 return; | 420 return; |
| 335 } | 421 } |
| 336 | 422 |
| 337 scoped_ptr<WindowedIncognitoObserver> incognito_observer( | 423 scoped_ptr<WindowedIncognitoObserver> incognito_observer( |
| 338 new WindowedIncognitoObserver); | 424 new WindowedIncognitoObserver); |
| 339 | 425 |
| 340 chromeos::DebugDaemonClient* client = | 426 chromeos::DebugDaemonClient* client = |
| 341 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); | 427 chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); |
| 342 | 428 |
| 429 std::vector<std::string> command = base::SplitString( |
| 430 command_selector_.Select(), kPerfCommandDelimiter, |
| 431 base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); |
| 343 client->GetPerfOutput( | 432 client->GetPerfOutput( |
| 344 collection_params_.collection_duration().InSeconds(), | 433 collection_params_.collection_duration().InSeconds(), command, |
| 345 base::Bind(&PerfProvider::ParseOutputProtoIfValid, | 434 base::Bind(&PerfProvider::ParseOutputProtoIfValid, |
| 346 weak_factory_.GetWeakPtr(), base::Passed(&incognito_observer), | 435 weak_factory_.GetWeakPtr(), base::Passed(&incognito_observer), |
| 347 base::Passed(&sampled_profile))); | 436 base::Passed(&sampled_profile))); |
| 348 } | 437 } |
| 349 | 438 |
| 350 void PerfProvider::DoPeriodicCollection() { | 439 void PerfProvider::DoPeriodicCollection() { |
| 351 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile); | 440 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile); |
| 352 sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION); | 441 sampled_profile->set_trigger_event(SampledProfile::PERIODIC_COLLECTION); |
| 353 | 442 |
| 354 CollectIfNecessary(sampled_profile.Pass()); | 443 CollectIfNecessary(sampled_profile.Pass()); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 373 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile); | 462 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile); |
| 374 sampled_profile->set_trigger_event(SampledProfile::RESTORE_SESSION); | 463 sampled_profile->set_trigger_event(SampledProfile::RESTORE_SESSION); |
| 375 sampled_profile->set_ms_after_restore(time_after_restore.InMilliseconds()); | 464 sampled_profile->set_ms_after_restore(time_after_restore.InMilliseconds()); |
| 376 sampled_profile->set_num_tabs_restored(num_tabs_restored); | 465 sampled_profile->set_num_tabs_restored(num_tabs_restored); |
| 377 | 466 |
| 378 CollectIfNecessary(sampled_profile.Pass()); | 467 CollectIfNecessary(sampled_profile.Pass()); |
| 379 last_session_restore_collection_time_ = base::TimeTicks::Now(); | 468 last_session_restore_collection_time_ = base::TimeTicks::Now(); |
| 380 } | 469 } |
| 381 | 470 |
| 382 } // namespace metrics | 471 } // namespace metrics |
| OLD | NEW |