Chromium Code Reviews| Index: chrome/browser/metrics/perf_provider_chromeos.cc |
| diff --git a/chrome/browser/metrics/perf_provider_chromeos.cc b/chrome/browser/metrics/perf_provider_chromeos.cc |
| index efa0d00dea7efbfa886af51959877dc2879316c9..0f1cac8acf637402dbf1b1583599c029b6b8c282 100644 |
| --- a/chrome/browser/metrics/perf_provider_chromeos.cc |
| +++ b/chrome/browser/metrics/perf_provider_chromeos.cc |
| @@ -24,26 +24,10 @@ |
| namespace { |
| -// Default time in seconds between invocations of perf. |
| -// This period is roughly 6.5 hours. |
| -// This is chosen to be relatively prime with the number of seconds in: |
| -// - one minute (60) |
| -// - one hour (3600) |
| -// - one day (86400) |
| -const size_t kPerfCommandIntervalDefaultSeconds = 23093; |
| - |
| -// The first collection interval is different from the interval above. This is |
| -// because we want to collect the first profile quickly after Chrome is started. |
| -// If this period is too long, the user will log off and Chrome will be killed |
| -// before it is triggered. The following 2 variables determine the upper and |
| -// lower bound on the interval. |
| -// The reason we do not always want to collect the initial profile after a fixed |
| -// period is to not over-represent task X in the profile where task X always |
| -// runs at a fixed period after start-up. By selecting a period randomly between |
| -// a lower and upper bound, we will hopefully collect a more fair profile. |
| -const size_t kPerfCommandStartIntervalLowerBoundMinutes = 10; |
| - |
| -const size_t kPerfCommandStartIntervalUpperBoundMinutes = 20; |
| +// Partition time since the epoch into successive intervals of this size. In |
| +// each interval that hasn't passed, pick a random time to collect a profile. |
| +// This interval is twenty-four hours. |
|
Ilya Sherman
2014/05/29 22:56:49
nit: Please update this comment.
Simon Que
2014/05/30 01:21:45
Done.
|
| +const size_t kPerfProfilingIntervalMs = 24 * 60 * 60 * 1000; |
| // Default time in seconds perf is run for. |
| const size_t kPerfCommandDurationDefaultSeconds = 2; |
| @@ -119,6 +103,7 @@ class WindowedIncognitoObserver : public chrome::BrowserListObserver { |
| PerfProvider::PerfProvider() |
| : login_observer_(this), |
| + next_profiling_interval_start_(base::TimeTicks::Now()), |
| weak_factory_(this) { |
| // Register the login observer with LoginState. |
| chromeos::LoginState::Get()->AddObserver(&login_observer_); |
| @@ -135,7 +120,7 @@ PerfProvider::~PerfProvider() { |
| chromeos::LoginState::Get()->RemoveObserver(&login_observer_); |
| } |
| -bool PerfProvider::GetPerfData(std::vector<PerfDataProto>* perf_data) { |
| +bool PerfProvider::GetPerfData(std::vector<SampledProfile>* perf_data) { |
| DCHECK(CalledOnValidThread()); |
| if (cached_perf_data_.empty()) { |
| AddToPerfHistogram(NOT_READY_TO_UPLOAD); |
| @@ -160,10 +145,8 @@ void PerfProvider::LoginObserver::LoggedInStateChanged() { |
| } |
| void PerfProvider::Activate() { |
|
Ilya Sherman
2014/05/29 22:56:49
nit: It might be wise to rename this method to som
Simon Que
2014/05/30 01:21:45
Done.
|
| - size_t collection_interval_minutes = base::RandInt( |
| - kPerfCommandStartIntervalLowerBoundMinutes, |
| - kPerfCommandStartIntervalUpperBoundMinutes); |
| - ScheduleCollection(base::TimeDelta::FromMinutes(collection_interval_minutes)); |
| + login_time_ = base::TimeTicks::Now(); |
| + ScheduleCollection(); |
| } |
| void PerfProvider::Deactivate() { |
| @@ -171,16 +154,29 @@ void PerfProvider::Deactivate() { |
| timer_.Stop(); |
| } |
| -void PerfProvider::ScheduleCollection(const base::TimeDelta& interval) { |
| +void PerfProvider::ScheduleCollection() { |
| DCHECK(CalledOnValidThread()); |
| if (timer_.IsRunning()) |
| return; |
| - timer_.Start(FROM_HERE, interval, this, |
| - &PerfProvider::CollectIfNecessaryAndReschedule); |
| + // Pick a random time in the current interval. |
| + base::TimeTicks scheduled_time = |
| + next_profiling_interval_start_ + |
| + base::TimeDelta::FromMilliseconds( |
| + base::RandGenerator(kPerfProfilingIntervalMs)); |
| + |
| + // If the scheduled time has already passed in the time it took to make the |
| + // above calculations, trigger the collection event immediately. |
| + base::TimeTicks now = base::TimeTicks::Now(); |
| + if (scheduled_time < now) { |
| + scheduled_time = now; |
| + } |
|
Ilya Sherman
2014/05/29 22:56:49
nit: No need for curly braces.
Simon Que
2014/05/30 01:21:45
Done.
|
| + timer_.Start(FROM_HERE, scheduled_time - now, this, |
| + &PerfProvider::DoPeriodicCollection); |
| } |
| -void PerfProvider::CollectIfNecessary() { |
| +void PerfProvider::CollectIfNecessary( |
| + SampledProfile::TriggerEvent trigger_event) { |
| DCHECK(CalledOnValidThread()); |
| // Do not collect further data if we've already collected a substantial amount |
| @@ -213,17 +209,22 @@ void PerfProvider::CollectIfNecessary() { |
| client->GetPerfData(collection_duration.InSeconds(), |
| base::Bind(&PerfProvider::ParseProtoIfValid, |
| weak_factory_.GetWeakPtr(), |
| - base::Passed(&incognito_observer))); |
| + base::Passed(&incognito_observer), |
| + trigger_event)); |
| } |
| -void PerfProvider::CollectIfNecessaryAndReschedule() { |
| - CollectIfNecessary(); |
| - ScheduleCollection( |
| - base::TimeDelta::FromSeconds(kPerfCommandIntervalDefaultSeconds)); |
| +void PerfProvider::DoPeriodicCollection() { |
| + CollectIfNecessary(SampledProfile::PERIODIC_COLLECTION); |
| + |
| + // Update the profiling interval tracker to the start of the next interval. |
| + next_profiling_interval_start_ += |
| + base::TimeDelta::FromMilliseconds(kPerfProfilingIntervalMs); |
|
Ilya Sherman
2014/05/29 22:56:49
nit: I think it would be slightly better to reset
Simon Que
2014/05/30 01:21:45
Done.
|
| + ScheduleCollection(); |
| } |
| void PerfProvider::ParseProtoIfValid( |
| scoped_ptr<WindowedIncognitoObserver> incognito_observer, |
| + SampledProfile::TriggerEvent trigger_event, |
| const std::vector<uint8>& data) { |
| DCHECK(CalledOnValidThread()); |
| @@ -238,10 +239,16 @@ void PerfProvider::ParseProtoIfValid( |
| return; |
| } |
| - // Append a new PerfDataProto to the |cached_perf_data_| vector and swap in |
| - // the contents. |
| + // Populate a profile collection protobuf with the collected perf data and |
| + // extra metadata. |
| cached_perf_data_.resize(cached_perf_data_.size() + 1); |
| - cached_perf_data_.back().Swap(&perf_data_proto); |
| + SampledProfile& collection_data = cached_perf_data_.back(); |
| + collection_data.set_trigger_event(trigger_event); |
| + collection_data.set_ms_after_boot(perf_data_proto.timestamp_sec()); |
|
Ilya Sherman
2014/05/29 22:56:49
You are still assigning seconds to a millisecond f
Simon Que
2014/05/30 01:21:45
Done.
|
| + collection_data. |
| + set_ms_after_login((base::TimeTicks::Now() - login_time_) |
|
Ilya Sherman
2014/05/29 22:56:49
nit: Please add a DCHECK that login_time_ is non-n
Simon Que
2014/05/30 01:21:45
Done.
|
| + .InMilliseconds()); |
| + *collection_data.mutable_perf_data() = perf_data_proto; |
| } |
| } // namespace metrics |