Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(469)

Side by Side Diff: chrome/browser/metrics/perf/perf_provider_chromeos.cc

Issue 1392153003: PerfProvider: Get collection parameters from Finch (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@perf_commands
Patch Set: Address comments on PS3 Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <algorithm>
8 #include <map>
8 #include <string> 9 #include <string>
9 10
10 #include "base/bind.h" 11 #include "base/bind.h"
11 #include "base/callback.h" 12 #include "base/callback.h"
12 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
14 #include "base/metrics/field_trial.h"
13 #include "base/metrics/histogram.h" 15 #include "base/metrics/histogram.h"
14 #include "base/rand_util.h" 16 #include "base/rand_util.h"
17 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_split.h" 18 #include "base/strings/string_split.h"
16 #include "base/threading/sequenced_worker_pool.h" 19 #include "base/threading/sequenced_worker_pool.h"
17 #include "chrome/browser/metrics/perf/windowed_incognito_observer.h" 20 #include "chrome/browser/metrics/perf/windowed_incognito_observer.h"
18 #include "chrome/browser/ui/browser_list.h" 21 #include "chrome/browser/ui/browser_list.h"
19 #include "chromeos/dbus/dbus_thread_manager.h" 22 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "chromeos/dbus/debug_daemon_client.h" 23 #include "chromeos/dbus/debug_daemon_client.h"
24 #include "components/variations/variations_associated_data.h"
21 25
22 namespace metrics { 26 namespace metrics {
23 27
24 namespace { 28 namespace {
25 29
30 const char kCWPFieldTrialName[] = "ChromeOSWideProfilingCollection";
31
26 // Limit the total size of protobufs that can be cached, so they don't take up 32 // Limit the total size of protobufs that can be cached, so they don't take up
27 // too much memory. If the size of cached protobufs exceeds this value, stop 33 // too much memory. If the size of cached protobufs exceeds this value, stop
28 // collecting further perf data. The current value is 4 MB. 34 // collecting further perf data. The current value is 4 MB.
29 const size_t kCachedPerfDataProtobufSizeThreshold = 4 * 1024 * 1024; 35 const size_t kCachedPerfDataProtobufSizeThreshold = 4 * 1024 * 1024;
30 36
31 // This is used to space out session restore collections in the face of several 37 // This is used to space out session restore collections in the face of several
32 // notifications in a short period of time. There should be no less than this 38 // notifications in a short period of time. There should be no less than this
33 // much time between collections. 39 // much time between collections.
34 const int kMinIntervalBetweenSessionRestoreCollectionsInSec = 30; 40 const int kMinIntervalBetweenSessionRestoreCollectionsInSec = 30;
35 41
(...skipping 25 matching lines...) Expand all
61 bool IsNormalUserLoggedIn() { 67 bool IsNormalUserLoggedIn() {
62 return chromeos::LoginState::Get()->IsUserAuthenticated(); 68 return chromeos::LoginState::Get()->IsUserAuthenticated();
63 } 69 }
64 70
65 // Returns a random TimeDelta between zero and |max|. 71 // Returns a random TimeDelta between zero and |max|.
66 base::TimeDelta RandomTimeDelta(base::TimeDelta max) { 72 base::TimeDelta RandomTimeDelta(base::TimeDelta max) {
67 return base::TimeDelta::FromMicroseconds( 73 return base::TimeDelta::FromMicroseconds(
68 base::RandGenerator(max.InMicroseconds())); 74 base::RandGenerator(max.InMicroseconds()));
69 } 75 }
70 76
77 // Gets parameter named by |key| from the map. If it is present and is an
78 // integer, stores the result in |out| and return true. Otherwise return false.
79 bool GetInt64Param(const std::map<std::string, std::string>& params,
80 const std::string& key,
81 int64* out) {
82 auto it = params.find(key);
83 if (it == params.end())
84 return false;
85 int64 value;
86 // NB: StringToInt64 will set value even if the conversion fails.
87 if (!base::StringToInt64(it->second, &value))
88 return false;
89 *out = value;
90 return true;
91 }
92
93 // Parses the key. e.g.: "PerfCommand::arm::0" returns "arm"
94 bool ExtractPerfCommandCpuSpecifier(const std::string& key,
95 std::string* cpu_specifier) {
96 std::vector<std::string> tokens;
97 base::SplitStringUsingSubstr(key, "::", &tokens);
98 if (tokens.size() != 3)
99 return false;
100 if (tokens[0] != "PerfCommand")
101 return false;
102 *cpu_specifier = tokens[1];
103 // tokens[2] is just a unique string (usually an index).
104 return true;
105 }
106
71 // Hopefully we never need a space in a command argument. 107 // Hopefully we never need a space in a command argument.
72 const char kPerfCommandDelimiter[] = " "; 108 const char kPerfCommandDelimiter[] = " ";
73 109
74 const char kPerfRecordCyclesCmd[] = 110 const char kPerfRecordCyclesCmd[] =
75 "perf record -a -e cycles -c 1000003"; 111 "perf record -a -e cycles -c 1000003";
76 112
77 const char kPerfRecordCallgraphCmd[] = 113 const char kPerfRecordCallgraphCmd[] =
78 "perf record -a -e cycles -g -c 4000037"; 114 "perf record -a -e cycles -g -c 4000037";
79 115
80 const char kPerfRecordLBRCmd[] = 116 const char kPerfRecordLBRCmd[] =
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 /* max_collection_delay = */ base::TimeDelta::FromSeconds(5)), 213 /* max_collection_delay = */ base::TimeDelta::FromSeconds(5)),
178 /* restore_session = */ PerfProvider::CollectionParams::TriggerParams( 214 /* restore_session = */ PerfProvider::CollectionParams::TriggerParams(
179 /* sampling_factor = */ 10, 215 /* sampling_factor = */ 10,
180 /* max_collection_delay = */ base::TimeDelta::FromSeconds(10))); 216 /* max_collection_delay = */ base::TimeDelta::FromSeconds(10)));
181 217
182 PerfProvider::PerfProvider() 218 PerfProvider::PerfProvider()
183 : collection_params_(kDefaultParameters), 219 : collection_params_(kDefaultParameters),
184 login_observer_(this), 220 login_observer_(this),
185 next_profiling_interval_start_(base::TimeTicks::Now()), 221 next_profiling_interval_start_(base::TimeTicks::Now()),
186 weak_factory_(this) { 222 weak_factory_(this) {
187 command_selector_.SetOdds( 223 CHECK(command_selector_.SetOdds(
188 internal::GetDefaultCommandsForCpu(GetCPUIdentity())), 224 internal::GetDefaultCommandsForCpu(GetCPUIdentity())));
225 std::map<std::string, std::string> params;
226 if (variations::GetVariationParams(kCWPFieldTrialName, &params))
227 SetCollectionParamsFromVariationParams(params);
189 228
190 // Register the login observer with LoginState. 229 // Register the login observer with LoginState.
191 chromeos::LoginState::Get()->AddObserver(&login_observer_); 230 chromeos::LoginState::Get()->AddObserver(&login_observer_);
192 231
193 // Register as an observer of power manager events. 232 // Register as an observer of power manager events.
194 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()-> 233 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->
195 AddObserver(this); 234 AddObserver(this);
196 235
197 // Register as an observer of session restore. 236 // Register as an observer of session restore.
198 on_session_restored_callback_subscription_ = 237 on_session_restored_callback_subscription_ =
199 SessionRestore::RegisterOnSessionRestoredCallback( 238 SessionRestore::RegisterOnSessionRestoredCallback(
200 base::Bind(&PerfProvider::OnSessionRestoreDone, 239 base::Bind(&PerfProvider::OnSessionRestoreDone,
201 weak_factory_.GetWeakPtr())); 240 weak_factory_.GetWeakPtr()));
202 241
203 // Check the login state. At the time of writing, this class is instantiated 242 // Check the login state. At the time of writing, this class is instantiated
204 // before login. A subsequent login would activate the profiling. However, 243 // before login. A subsequent login would activate the profiling. However,
205 // that behavior may change in the future so that the user is already logged 244 // that behavior may change in the future so that the user is already logged
206 // when this class is instantiated. By calling LoggedInStateChanged() here, 245 // when this class is instantiated. By calling LoggedInStateChanged() here,
207 // PerfProvider will recognize that the system is already logged in. 246 // PerfProvider will recognize that the system is already logged in.
208 login_observer_.LoggedInStateChanged(); 247 login_observer_.LoggedInStateChanged();
209 } 248 }
210 249
211 PerfProvider::~PerfProvider() { 250 PerfProvider::~PerfProvider() {
212 chromeos::LoginState::Get()->RemoveObserver(&login_observer_); 251 chromeos::LoginState::Get()->RemoveObserver(&login_observer_);
213 } 252 }
214 253
254 namespace internal {
255
256 std::string FindBestCpuSpecifierFromParams(
257 const std::map<std::string, std::string>& params,
258 const CPUIdentity& cpuid) {
259 std::string ret;
260 // The CPU specified in the variation params could be "default", a system
261 // architecture, a CPU microarchitecture, or a CPU model substring. We should
262 // prefer to match the most specific.
263 enum MatchSpecificity {
264 NO_MATCH,
265 DEFAULT,
266 SYSTEM_ARCH,
267 CPU_UARCH,
268 CPU_MODEL,
269 };
270 MatchSpecificity match_level = NO_MATCH;
271
272 const std::string intel_uarch = GetIntelUarch(cpuid);
273 const std::string simplified_cpu_model =
274 SimplifyCPUModelName(cpuid.model_name);
275
276 for (const auto& key_val : params) {
277 const std::string& key = key_val.first;
278
279 std::string cpu_specifier;
280 if (!ExtractPerfCommandCpuSpecifier(key, &cpu_specifier))
281 continue;
282
283 if (match_level < DEFAULT && cpu_specifier == "default") {
284 match_level = DEFAULT;
285 ret = cpu_specifier;
286 }
287 if (match_level < SYSTEM_ARCH && cpu_specifier == cpuid.arch) {
288 match_level = SYSTEM_ARCH;
289 ret = cpu_specifier;
290 }
291 if (match_level < CPU_UARCH &&
292 !intel_uarch.empty() && cpu_specifier == intel_uarch) {
293 match_level = CPU_UARCH;
294 ret = cpu_specifier;
295 }
296 if (match_level < CPU_MODEL &&
297 simplified_cpu_model.find(cpu_specifier) != std::string::npos) {
298 match_level = CPU_MODEL;
299 ret = cpu_specifier;
300 }
301 }
302 return ret;
303 }
304
305 } // namespace internal
306
307 void PerfProvider::SetCollectionParamsFromVariationParams(
308 const std::map<std::string, std::string>& params) {
309 int64 value;
310 if (GetInt64Param(params, "ProfileCollectionDurationSec", &value)) {
311 collection_params_.set_collection_duration(
312 base::TimeDelta::FromSeconds(value));
313 }
314 if (GetInt64Param(params, "PeriodicProfilingIntervalMs", &value)) {
315 collection_params_.set_periodic_interval(
316 base::TimeDelta::FromMilliseconds(value));
317 }
318 if (GetInt64Param(params, "ResumeFromSuspend::SamplingFactor", &value)) {
319 collection_params_.mutable_resume_from_suspend()
320 ->set_sampling_factor(value);
321 }
322 if (GetInt64Param(params, "ResumeFromSuspend::MaxDelaySec", &value)) {
323 collection_params_.mutable_resume_from_suspend()->set_max_collection_delay(
324 base::TimeDelta::FromSeconds(value));
325 }
326 if (GetInt64Param(params, "RestoreSession::SamplingFactor", &value)) {
327 collection_params_.mutable_restore_session()->set_sampling_factor(value);
328 }
329 if (GetInt64Param(params, "RestoreSession::MaxDelaySec", &value)) {
330 collection_params_.mutable_restore_session()->set_max_collection_delay(
331 base::TimeDelta::FromSeconds(value));
332 }
333
334 const std::string best_cpu_specifier =
335 internal::FindBestCpuSpecifierFromParams(params, GetCPUIdentity());
336
337 if (best_cpu_specifier.empty()) // No matching cpu specifier. Keep defaults.
338 return;
339
340 std::vector<RandomSelector::WeightAndValue> commands;
341 for (const auto& key_val : params) {
342 const std::string& key = key_val.first;
343 const std::string& val = key_val.second;
344
345 std::string cpu_specifier;
346 if (!ExtractPerfCommandCpuSpecifier(key, &cpu_specifier))
347 continue;
348 if (cpu_specifier != best_cpu_specifier)
349 continue;
350
351 auto split = val.find(" ");
352 if (split == std::string::npos)
353 continue; // Just drop invalid commands.
354 std::string weight_str = std::string(val.begin(), val.begin() + split);
355
356 double weight;
357 if (!(base::StringToDouble(weight_str, &weight) && weight > 0.0))
358 continue; // Just drop invalid commands.
359 std::string command(val.begin() + split + 1, val.end());
360 commands.push_back(RandomSelector::WeightAndValue(weight, command));
361 }
362 command_selector_.SetOdds(commands);
363 }
364
215 bool PerfProvider::GetSampledProfiles( 365 bool PerfProvider::GetSampledProfiles(
216 std::vector<SampledProfile>* sampled_profiles) { 366 std::vector<SampledProfile>* sampled_profiles) {
217 DCHECK(CalledOnValidThread()); 367 DCHECK(CalledOnValidThread());
218 if (cached_perf_data_.empty()) { 368 if (cached_perf_data_.empty()) {
219 AddToPerfHistogram(NOT_READY_TO_UPLOAD); 369 AddToPerfHistogram(NOT_READY_TO_UPLOAD);
220 return false; 370 return false;
221 } 371 }
222 372
223 sampled_profiles->swap(cached_perf_data_); 373 sampled_profiles->swap(cached_perf_data_);
224 cached_perf_data_.clear(); 374 cached_perf_data_.clear();
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile); 612 scoped_ptr<SampledProfile> sampled_profile(new SampledProfile);
463 sampled_profile->set_trigger_event(SampledProfile::RESTORE_SESSION); 613 sampled_profile->set_trigger_event(SampledProfile::RESTORE_SESSION);
464 sampled_profile->set_ms_after_restore(time_after_restore.InMilliseconds()); 614 sampled_profile->set_ms_after_restore(time_after_restore.InMilliseconds());
465 sampled_profile->set_num_tabs_restored(num_tabs_restored); 615 sampled_profile->set_num_tabs_restored(num_tabs_restored);
466 616
467 CollectIfNecessary(sampled_profile.Pass()); 617 CollectIfNecessary(sampled_profile.Pass());
468 last_session_restore_collection_time_ = base::TimeTicks::Now(); 618 last_session_restore_collection_time_ = base::TimeTicks::Now();
469 } 619 }
470 620
471 } // namespace metrics 621 } // namespace metrics
OLDNEW
« no previous file with comments | « chrome/browser/metrics/perf/perf_provider_chromeos.h ('k') | chrome/browser/metrics/perf/perf_provider_chromeos_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698