| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/metrics/call_stack_profile_metrics_provider.h" | 5 #include "components/metrics/call_stack_profile_metrics_provider.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 namespace metrics { | 32 namespace metrics { |
| 33 | 33 |
| 34 namespace { | 34 namespace { |
| 35 | 35 |
| 36 // ProfilesState -------------------------------------------------------------- | 36 // ProfilesState -------------------------------------------------------------- |
| 37 | 37 |
| 38 // A set of profiles and the CallStackProfileMetricsProvider state associated | 38 // A set of profiles and the CallStackProfileMetricsProvider state associated |
| 39 // with them. | 39 // with them. |
| 40 struct ProfilesState { | 40 struct ProfilesState { |
| 41 ProfilesState(const CallStackProfileParams& params, | 41 ProfilesState(const CallStackProfileParams& params, |
| 42 const base::StackSamplingProfiler::CallStackProfiles& profiles, | 42 base::StackSamplingProfiler::CallStackProfiles profiles, |
| 43 base::TimeTicks start_timestamp); | 43 base::TimeTicks start_timestamp); |
| 44 ProfilesState(ProfilesState&&); |
| 45 ProfilesState& operator=(ProfilesState&&); |
| 44 | 46 |
| 45 // The metrics-related parameters provided to | 47 // The metrics-related parameters provided to |
| 46 // CallStackProfileMetricsProvider::GetProfilerCallback(). | 48 // CallStackProfileMetricsProvider::GetProfilerCallback(). |
| 47 CallStackProfileParams params; | 49 CallStackProfileParams params; |
| 48 | 50 |
| 49 // The call stack profiles collected by the profiler. | 51 // The call stack profiles collected by the profiler. |
| 50 base::StackSamplingProfiler::CallStackProfiles profiles; | 52 base::StackSamplingProfiler::CallStackProfiles profiles; |
| 51 | 53 |
| 52 // The time at which the CallStackProfileMetricsProvider became aware of the | 54 // The time at which the CallStackProfileMetricsProvider became aware of the |
| 53 // request for profiling. In particular, this is when callback was requested | 55 // request for profiling. In particular, this is when callback was requested |
| 54 // via CallStackProfileMetricsProvider::GetProfilerCallback(). Used to | 56 // via CallStackProfileMetricsProvider::GetProfilerCallback(). Used to |
| 55 // determine if collection was disabled during the collection of the profile. | 57 // determine if collection was disabled during the collection of the profile. |
| 56 base::TimeTicks start_timestamp; | 58 base::TimeTicks start_timestamp; |
| 59 |
| 60 private: |
| 61 DISALLOW_COPY_AND_ASSIGN(ProfilesState); |
| 57 }; | 62 }; |
| 58 | 63 |
| 59 ProfilesState::ProfilesState( | 64 ProfilesState::ProfilesState( |
| 60 const CallStackProfileParams& params, | 65 const CallStackProfileParams& params, |
| 61 const base::StackSamplingProfiler::CallStackProfiles& profiles, | 66 base::StackSamplingProfiler::CallStackProfiles profiles, |
| 62 base::TimeTicks start_timestamp) | 67 base::TimeTicks start_timestamp) |
| 63 : params(params), | 68 : params(params), |
| 64 profiles(profiles), | 69 profiles(std::move(profiles)), |
| 65 start_timestamp(start_timestamp) { | 70 start_timestamp(start_timestamp) {} |
| 66 } | 71 |
| 72 ProfilesState::ProfilesState(ProfilesState&&) = default; |
| 73 |
| 74 // Some versions of GCC need this for push_back to work with std::move. |
| 75 ProfilesState& ProfilesState::operator=(ProfilesState&&) = default; |
| 67 | 76 |
| 68 // PendingProfiles ------------------------------------------------------------ | 77 // PendingProfiles ------------------------------------------------------------ |
| 69 | 78 |
| 70 // Singleton class responsible for retaining profiles received via the callback | 79 // Singleton class responsible for retaining profiles received via the callback |
| 71 // created by CallStackProfileMetricsProvider::GetProfilerCallback(). These are | 80 // created by CallStackProfileMetricsProvider::GetProfilerCallback(). These are |
| 72 // then sent to UMA on the invocation of | 81 // then sent to UMA on the invocation of |
| 73 // CallStackProfileMetricsProvider::ProvideGeneralMetrics(). We need to store | 82 // CallStackProfileMetricsProvider::ProvideGeneralMetrics(). We need to store |
| 74 // the profiles outside of a CallStackProfileMetricsProvider instance since | 83 // the profiles outside of a CallStackProfileMetricsProvider instance since |
| 75 // callers may start profiling before the CallStackProfileMetricsProvider is | 84 // callers may start profiling before the CallStackProfileMetricsProvider is |
| 76 // created. | 85 // created. |
| 77 // | 86 // |
| 78 // Member functions on this class may be called on any thread. | 87 // Member functions on this class may be called on any thread. |
| 79 class PendingProfiles { | 88 class PendingProfiles { |
| 80 public: | 89 public: |
| 81 static PendingProfiles* GetInstance(); | 90 static PendingProfiles* GetInstance(); |
| 82 | 91 |
| 83 void Clear(); | 92 void Clear(); |
| 84 void Swap(std::vector<ProfilesState>* profiles); | 93 void Swap(std::vector<ProfilesState>* profiles); |
| 85 | 94 |
| 86 // Enables the collection of profiles by CollectProfilesIfCollectionEnabled if | 95 // Enables the collection of profiles by CollectProfilesIfCollectionEnabled if |
| 87 // |enabled| is true. Otherwise, clears current profiles and ignores profiles | 96 // |enabled| is true. Otherwise, clears current profiles and ignores profiles |
| 88 // provided to future invocations of CollectProfilesIfCollectionEnabled. | 97 // provided to future invocations of CollectProfilesIfCollectionEnabled. |
| 89 void SetCollectionEnabled(bool enabled); | 98 void SetCollectionEnabled(bool enabled); |
| 90 | 99 |
| 91 // True if profiles are being collected. | 100 // True if profiles are being collected. |
| 92 bool IsCollectionEnabled() const; | 101 bool IsCollectionEnabled() const; |
| 93 | 102 |
| 94 // Adds |profile| to the list of profiles if collection is enabled. | 103 // Adds |profiles| to the list of profiles if collection is enabled; it is |
| 95 void CollectProfilesIfCollectionEnabled(const ProfilesState& profiles); | 104 // not const& because it must be passed with std::move. |
| 105 void CollectProfilesIfCollectionEnabled(ProfilesState profiles); |
| 96 | 106 |
| 97 // Allows testing against the initial state multiple times. | 107 // Allows testing against the initial state multiple times. |
| 98 void ResetToDefaultStateForTesting(); | 108 void ResetToDefaultStateForTesting(); |
| 99 | 109 |
| 100 private: | 110 private: |
| 101 friend struct base::DefaultSingletonTraits<PendingProfiles>; | 111 friend struct base::DefaultSingletonTraits<PendingProfiles>; |
| 102 | 112 |
| 103 PendingProfiles(); | 113 PendingProfiles(); |
| 104 ~PendingProfiles(); | 114 ~PendingProfiles(); |
| 105 | 115 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 last_collection_disable_time_ = base::TimeTicks::Now(); | 156 last_collection_disable_time_ = base::TimeTicks::Now(); |
| 147 } | 157 } |
| 148 } | 158 } |
| 149 | 159 |
| 150 bool PendingProfiles::IsCollectionEnabled() const { | 160 bool PendingProfiles::IsCollectionEnabled() const { |
| 151 base::AutoLock scoped_lock(lock_); | 161 base::AutoLock scoped_lock(lock_); |
| 152 return collection_enabled_; | 162 return collection_enabled_; |
| 153 } | 163 } |
| 154 | 164 |
| 155 void PendingProfiles::CollectProfilesIfCollectionEnabled( | 165 void PendingProfiles::CollectProfilesIfCollectionEnabled( |
| 156 const ProfilesState& profiles) { | 166 ProfilesState profiles) { |
| 157 base::AutoLock scoped_lock(lock_); | 167 base::AutoLock scoped_lock(lock_); |
| 158 | 168 |
| 159 // Only collect if collection is not disabled and hasn't been disabled | 169 // Only collect if collection is not disabled and hasn't been disabled |
| 160 // since the start of collection for this profile. | 170 // since the start of collection for this profile. |
| 161 if (!collection_enabled_ || | 171 if (!collection_enabled_ || |
| 162 (!last_collection_disable_time_.is_null() && | 172 (!last_collection_disable_time_.is_null() && |
| 163 last_collection_disable_time_ >= profiles.start_timestamp)) { | 173 last_collection_disable_time_ >= profiles.start_timestamp)) { |
| 164 return; | 174 return; |
| 165 } | 175 } |
| 166 | 176 |
| 167 profiles_.push_back(profiles); | 177 profiles_.push_back(std::move(profiles)); |
| 168 } | 178 } |
| 169 | 179 |
| 170 void PendingProfiles::ResetToDefaultStateForTesting() { | 180 void PendingProfiles::ResetToDefaultStateForTesting() { |
| 171 base::AutoLock scoped_lock(lock_); | 181 base::AutoLock scoped_lock(lock_); |
| 172 | 182 |
| 173 collection_enabled_ = true; | 183 collection_enabled_ = true; |
| 174 last_collection_disable_time_ = base::TimeTicks(); | 184 last_collection_disable_time_ = base::TimeTicks(); |
| 175 profiles_.clear(); | 185 profiles_.clear(); |
| 176 } | 186 } |
| 177 | 187 |
| 178 // |collection_enabled_| is initialized to true to collect any profiles that are | 188 // |collection_enabled_| is initialized to true to collect any profiles that are |
| 179 // generated prior to creation of the CallStackProfileMetricsProvider. The | 189 // generated prior to creation of the CallStackProfileMetricsProvider. The |
| 180 // ultimate disposition of these pre-creation collected profiles will be | 190 // ultimate disposition of these pre-creation collected profiles will be |
| 181 // determined by the initial recording state provided to | 191 // determined by the initial recording state provided to |
| 182 // CallStackProfileMetricsProvider. | 192 // CallStackProfileMetricsProvider. |
| 183 PendingProfiles::PendingProfiles() : collection_enabled_(true) {} | 193 PendingProfiles::PendingProfiles() : collection_enabled_(true) {} |
| 184 | 194 |
| 185 PendingProfiles::~PendingProfiles() {} | 195 PendingProfiles::~PendingProfiles() {} |
| 186 | 196 |
| 187 // Functions to process completed profiles ------------------------------------ | 197 // Functions to process completed profiles ------------------------------------ |
| 188 | 198 |
| 189 // Will be invoked on either the main thread or the profiler's thread. Provides | 199 // Will be invoked on either the main thread or the profiler's thread. Provides |
| 190 // the profiles to PendingProfiles to append, if the collecting state allows. | 200 // the profiles to PendingProfiles to append, if the collecting state allows. |
| 191 void ReceiveCompletedProfilesImpl( | 201 void ReceiveCompletedProfilesImpl( |
| 192 const CallStackProfileParams& params, | 202 const CallStackProfileParams& params, |
| 193 base::TimeTicks start_timestamp, | 203 base::TimeTicks start_timestamp, |
| 194 const StackSamplingProfiler::CallStackProfiles& profiles) { | 204 StackSamplingProfiler::CallStackProfiles profiles) { |
| 195 PendingProfiles::GetInstance()->CollectProfilesIfCollectionEnabled( | 205 PendingProfiles::GetInstance()->CollectProfilesIfCollectionEnabled( |
| 196 ProfilesState(params, profiles, start_timestamp)); | 206 ProfilesState(params, std::move(profiles), start_timestamp)); |
| 197 } | 207 } |
| 198 | 208 |
| 199 // Invoked on an arbitrary thread. Ignores the provided profiles. | 209 // Invoked on an arbitrary thread. Ignores the provided profiles. |
| 200 void IgnoreCompletedProfiles( | 210 void IgnoreCompletedProfiles( |
| 201 const StackSamplingProfiler::CallStackProfiles& profiles) { | 211 StackSamplingProfiler::CallStackProfiles profiles) {} |
| 202 } | |
| 203 | 212 |
| 204 // Functions to encode protobufs ---------------------------------------------- | 213 // Functions to encode protobufs ---------------------------------------------- |
| 205 | 214 |
| 206 // The protobuf expects the MD5 checksum prefix of the module name. | 215 // The protobuf expects the MD5 checksum prefix of the module name. |
| 207 uint64_t HashModuleFilename(const base::FilePath& filename) { | 216 uint64_t HashModuleFilename(const base::FilePath& filename) { |
| 208 const base::FilePath::StringType basename = filename.BaseName().value(); | 217 const base::FilePath::StringType basename = filename.BaseName().value(); |
| 209 // Copy the bytes in basename into a string buffer. | 218 // Copy the bytes in basename into a string buffer. |
| 210 size_t basename_length_in_bytes = | 219 size_t basename_length_in_bytes = |
| 211 basename.size() * sizeof(base::FilePath::CharType); | 220 basename.size() * sizeof(base::FilePath::CharType); |
| 212 std::string name_bytes(basename_length_in_bytes, '\0'); | 221 std::string name_bytes(basename_length_in_bytes, '\0'); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 return base::Bind(&IgnoreCompletedProfiles); | 400 return base::Bind(&IgnoreCompletedProfiles); |
| 392 | 401 |
| 393 return base::Bind(&ReceiveCompletedProfilesImpl, params, | 402 return base::Bind(&ReceiveCompletedProfilesImpl, params, |
| 394 base::TimeTicks::Now()); | 403 base::TimeTicks::Now()); |
| 395 } | 404 } |
| 396 | 405 |
| 397 // static | 406 // static |
| 398 void CallStackProfileMetricsProvider::ReceiveCompletedProfiles( | 407 void CallStackProfileMetricsProvider::ReceiveCompletedProfiles( |
| 399 const CallStackProfileParams& params, | 408 const CallStackProfileParams& params, |
| 400 base::TimeTicks start_timestamp, | 409 base::TimeTicks start_timestamp, |
| 401 const base::StackSamplingProfiler::CallStackProfiles& profiles) { | 410 base::StackSamplingProfiler::CallStackProfiles profiles) { |
| 402 ReceiveCompletedProfilesImpl(params, start_timestamp, profiles); | 411 ReceiveCompletedProfilesImpl(params, start_timestamp, std::move(profiles)); |
| 403 } | 412 } |
| 404 | 413 |
| 405 void CallStackProfileMetricsProvider::OnRecordingEnabled() { | 414 void CallStackProfileMetricsProvider::OnRecordingEnabled() { |
| 406 PendingProfiles::GetInstance()->SetCollectionEnabled(true); | 415 PendingProfiles::GetInstance()->SetCollectionEnabled(true); |
| 407 } | 416 } |
| 408 | 417 |
| 409 void CallStackProfileMetricsProvider::OnRecordingDisabled() { | 418 void CallStackProfileMetricsProvider::OnRecordingDisabled() { |
| 410 PendingProfiles::GetInstance()->SetCollectionEnabled(false); | 419 PendingProfiles::GetInstance()->SetCollectionEnabled(false); |
| 411 } | 420 } |
| 412 | 421 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 440 | 449 |
| 441 // static | 450 // static |
| 442 bool CallStackProfileMetricsProvider::IsReportingEnabledByFieldTrial() { | 451 bool CallStackProfileMetricsProvider::IsReportingEnabledByFieldTrial() { |
| 443 const std::string group_name = base::FieldTrialList::FindFullName( | 452 const std::string group_name = base::FieldTrialList::FindFullName( |
| 444 CallStackProfileMetricsProvider::kFieldTrialName); | 453 CallStackProfileMetricsProvider::kFieldTrialName); |
| 445 return group_name == | 454 return group_name == |
| 446 CallStackProfileMetricsProvider::kReportProfilesGroupName; | 455 CallStackProfileMetricsProvider::kReportProfilesGroupName; |
| 447 } | 456 } |
| 448 | 457 |
| 449 } // namespace metrics | 458 } // namespace metrics |
| OLD | NEW |