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 "base/profiler/stack_sampling_profiler.h" | 5 #include "base/profiler/stack_sampling_profiler.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 completed_callback_.Run(profiles); | 134 completed_callback_.Run(profiles); |
135 } | 135 } |
136 | 136 |
137 // Depending on how long the sampling takes and the length of the sampling | 137 // Depending on how long the sampling takes and the length of the sampling |
138 // interval, a burst of samples could take arbitrarily longer than | 138 // interval, a burst of samples could take arbitrarily longer than |
139 // samples_per_burst * sampling_interval. In this case, we (somewhat | 139 // samples_per_burst * sampling_interval. In this case, we (somewhat |
140 // arbitrarily) honor the number of samples requested rather than strictly | 140 // arbitrarily) honor the number of samples requested rather than strictly |
141 // adhering to the sampling intervals. Once we have established users for the | 141 // adhering to the sampling intervals. Once we have established users for the |
142 // StackSamplingProfiler and the collected data to judge, we may go the other | 142 // StackSamplingProfiler and the collected data to judge, we may go the other |
143 // way or make this behavior configurable. | 143 // way or make this behavior configurable. |
144 bool StackSamplingProfiler::SamplingThread::CollectProfile( | 144 void StackSamplingProfiler::SamplingThread::CollectProfile( |
145 CallStackProfile* profile, | 145 CallStackProfile* profile, |
146 TimeDelta* elapsed_time) { | 146 TimeDelta* elapsed_time, |
| 147 bool* was_stopped) { |
147 ElapsedTimer profile_timer; | 148 ElapsedTimer profile_timer; |
148 CallStackProfile current_profile; | 149 native_sampler_->ProfileRecordingStarting(&profile->modules); |
149 native_sampler_->ProfileRecordingStarting(¤t_profile.modules); | 150 profile->sampling_period = params_.sampling_interval; |
150 current_profile.sampling_period = params_.sampling_interval; | 151 *was_stopped = false; |
151 bool burst_completed = true; | |
152 TimeDelta previous_elapsed_sample_time; | 152 TimeDelta previous_elapsed_sample_time; |
153 for (int i = 0; i < params_.samples_per_burst; ++i) { | 153 for (int i = 0; i < params_.samples_per_burst; ++i) { |
154 if (i != 0) { | 154 if (i != 0) { |
155 // Always wait, even if for 0 seconds, so we can observe a signal on | 155 // Always wait, even if for 0 seconds, so we can observe a signal on |
156 // stop_event_. | 156 // stop_event_. |
157 if (stop_event_.TimedWait( | 157 if (stop_event_.TimedWait( |
158 std::max(params_.sampling_interval - previous_elapsed_sample_time, | 158 std::max(params_.sampling_interval - previous_elapsed_sample_time, |
159 TimeDelta()))) { | 159 TimeDelta()))) { |
160 burst_completed = false; | 160 *was_stopped = true; |
161 break; | 161 break; |
162 } | 162 } |
163 } | 163 } |
164 ElapsedTimer sample_timer; | 164 ElapsedTimer sample_timer; |
165 current_profile.samples.push_back(Sample()); | 165 profile->samples.push_back(Sample()); |
166 native_sampler_->RecordStackSample(¤t_profile.samples.back()); | 166 native_sampler_->RecordStackSample(&profile->samples.back()); |
167 previous_elapsed_sample_time = sample_timer.Elapsed(); | 167 previous_elapsed_sample_time = sample_timer.Elapsed(); |
168 } | 168 } |
169 | 169 |
170 *elapsed_time = profile_timer.Elapsed(); | 170 *elapsed_time = profile_timer.Elapsed(); |
171 current_profile.profile_duration = *elapsed_time; | 171 profile->profile_duration = *elapsed_time; |
172 native_sampler_->ProfileRecordingStopped(); | 172 native_sampler_->ProfileRecordingStopped(); |
173 | |
174 if (burst_completed) | |
175 *profile = current_profile; | |
176 | |
177 return burst_completed; | |
178 } | 173 } |
179 | 174 |
180 // In an analogous manner to CollectProfile() and samples exceeding the expected | 175 // In an analogous manner to CollectProfile() and samples exceeding the expected |
181 // total sampling time, bursts may also exceed the burst_interval. We adopt the | 176 // total sampling time, bursts may also exceed the burst_interval. We adopt the |
182 // same wait-and-see approach here. | 177 // same wait-and-see approach here. |
183 void StackSamplingProfiler::SamplingThread::CollectProfiles( | 178 void StackSamplingProfiler::SamplingThread::CollectProfiles( |
184 CallStackProfiles* profiles) { | 179 CallStackProfiles* profiles) { |
185 if (stop_event_.TimedWait(params_.initial_delay)) | 180 if (stop_event_.TimedWait(params_.initial_delay)) |
186 return; | 181 return; |
187 | 182 |
188 TimeDelta previous_elapsed_profile_time; | 183 TimeDelta previous_elapsed_profile_time; |
189 for (int i = 0; i < params_.bursts; ++i) { | 184 for (int i = 0; i < params_.bursts; ++i) { |
190 if (i != 0) { | 185 if (i != 0) { |
191 // Always wait, even if for 0 seconds, so we can observe a signal on | 186 // Always wait, even if for 0 seconds, so we can observe a signal on |
192 // stop_event_. | 187 // stop_event_. |
193 if (stop_event_.TimedWait( | 188 if (stop_event_.TimedWait( |
194 std::max(params_.burst_interval - previous_elapsed_profile_time, | 189 std::max(params_.burst_interval - previous_elapsed_profile_time, |
195 TimeDelta()))) | 190 TimeDelta()))) |
196 return; | 191 return; |
197 } | 192 } |
198 | 193 |
199 CallStackProfile profile; | 194 CallStackProfile profile; |
200 if (!CollectProfile(&profile, &previous_elapsed_profile_time)) | 195 bool was_stopped = false; |
| 196 CollectProfile(&profile, &previous_elapsed_profile_time, &was_stopped); |
| 197 if (!profile.samples.empty()) |
| 198 profiles->push_back(profile); |
| 199 |
| 200 if (was_stopped) |
201 return; | 201 return; |
202 profiles->push_back(profile); | |
203 } | 202 } |
204 } | 203 } |
205 | 204 |
206 void StackSamplingProfiler::SamplingThread::Stop() { | 205 void StackSamplingProfiler::SamplingThread::Stop() { |
207 stop_event_.Signal(); | 206 stop_event_.Signal(); |
208 } | 207 } |
209 | 208 |
210 // StackSamplingProfiler ------------------------------------------------------ | 209 // StackSamplingProfiler ------------------------------------------------------ |
211 | 210 |
212 StackSamplingProfiler::SamplingParams::SamplingParams() | 211 StackSamplingProfiler::SamplingParams::SamplingParams() |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 } | 266 } |
268 | 267 |
269 bool operator<(const StackSamplingProfiler::Frame &a, | 268 bool operator<(const StackSamplingProfiler::Frame &a, |
270 const StackSamplingProfiler::Frame &b) { | 269 const StackSamplingProfiler::Frame &b) { |
271 return (a.module_index < b.module_index) || | 270 return (a.module_index < b.module_index) || |
272 (a.module_index == b.module_index && | 271 (a.module_index == b.module_index && |
273 a.instruction_pointer < b.instruction_pointer); | 272 a.instruction_pointer < b.instruction_pointer); |
274 } | 273 } |
275 | 274 |
276 } // namespace base | 275 } // namespace base |
OLD | NEW |