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