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

Side by Side Diff: base/profiler/stack_sampling_profiler.cc

Issue 2444143002: Add process lifetime annotations to stack samples. (Closed)
Patch Set: Created 4 years, 1 month 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 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 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 void AsyncRunner::RunCallbackAndDeleteInstance( 74 void AsyncRunner::RunCallbackAndDeleteInstance(
75 std::unique_ptr<AsyncRunner> object_to_be_deleted, 75 std::unique_ptr<AsyncRunner> object_to_be_deleted,
76 const StackSamplingProfiler::CompletedCallback& callback, 76 const StackSamplingProfiler::CompletedCallback& callback,
77 scoped_refptr<SingleThreadTaskRunner> task_runner, 77 scoped_refptr<SingleThreadTaskRunner> task_runner,
78 const StackSamplingProfiler::CallStackProfiles& profiles) { 78 const StackSamplingProfiler::CallStackProfiles& profiles) {
79 callback.Run(profiles); 79 callback.Run(profiles);
80 // Delete the instance on the original calling thread. 80 // Delete the instance on the original calling thread.
81 task_runner->DeleteSoon(FROM_HERE, object_to_be_deleted.release()); 81 task_runner->DeleteSoon(FROM_HERE, object_to_be_deleted.release());
82 } 82 }
83 83
84 void ChangeAtomicFlags(volatile subtle::Atomic32* flags,
Mike Wittman 2016/10/24 22:28:14 Same comment about volatile.
bcwhite 2016/10/25 14:45:23 Done.
85 subtle::Atomic32 set,
86 subtle::Atomic32 clear) {
87 DCHECK(set != 0 || clear != 0);
88 DCHECK_EQ(0, set & clear);
89
90 subtle::Atomic32 bits = subtle::NoBarrier_Load(flags);
91 while (true) {
92 subtle::Atomic32 existing =
93 subtle::NoBarrier_CompareAndSwap(flags, bits, (bits | set) & ~clear);
94 if (existing == bits)
95 break;
96 bits = existing;
97 }
98 }
99
84 } // namespace 100 } // namespace
85 101
86 // StackSamplingProfiler::Module ---------------------------------------------- 102 // StackSamplingProfiler::Module ----------------------------------------------
87 103
88 StackSamplingProfiler::Module::Module() : base_address(0u) {} 104 StackSamplingProfiler::Module::Module() : base_address(0u) {}
89 StackSamplingProfiler::Module::Module(uintptr_t base_address, 105 StackSamplingProfiler::Module::Module(uintptr_t base_address,
90 const std::string& id, 106 const std::string& id,
91 const FilePath& filename) 107 const FilePath& filename)
92 : base_address(base_address), id(id), filename(filename) {} 108 : base_address(base_address), id(id), filename(filename) {}
93 109
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 // stop_event_. 180 // stop_event_.
165 if (stop_event_.TimedWait( 181 if (stop_event_.TimedWait(
166 std::max(params_.sampling_interval - previous_elapsed_sample_time, 182 std::max(params_.sampling_interval - previous_elapsed_sample_time,
167 TimeDelta()))) { 183 TimeDelta()))) {
168 *was_stopped = true; 184 *was_stopped = true;
169 break; 185 break;
170 } 186 }
171 } 187 }
172 ElapsedTimer sample_timer; 188 ElapsedTimer sample_timer;
173 profile->samples.push_back(Sample()); 189 profile->samples.push_back(Sample());
174 native_sampler_->RecordStackSample(&profile->samples.back()); 190 Sample& sample = profile->samples.back();
191 sample.process_phases = subtle::NoBarrier_Load(&process_phases_);
192 sample.current_activities = subtle::NoBarrier_Load(&current_activities_);
Mike Wittman 2016/10/24 22:28:14 The SuspendThread call in the native stack sampler
bcwhite 2016/10/25 14:45:23 Done.
Mike Wittman 2016/10/25 17:24:22 Sorry for not being specific: I was intending to s
bcwhite 2016/10/25 21:10:42 Done. Ya know... Callbacks only _look_ simple...
Mike Wittman 2016/10/26 16:28:17 Thanks. But it gets even more complicated. :) (See
193 native_sampler_->RecordStackSample(&sample);
175 previous_elapsed_sample_time = sample_timer.Elapsed(); 194 previous_elapsed_sample_time = sample_timer.Elapsed();
176 } 195 }
177 196
178 *elapsed_time = profile_timer.Elapsed(); 197 *elapsed_time = profile_timer.Elapsed();
179 profile->profile_duration = *elapsed_time; 198 profile->profile_duration = *elapsed_time;
180 native_sampler_->ProfileRecordingStopped(); 199 native_sampler_->ProfileRecordingStopped();
181 } 200 }
182 201
183 // In an analogous manner to CollectProfile() and samples exceeding the expected 202 // In an analogous manner to CollectProfile() and samples exceeding the expected
184 // total sampling time, bursts may also exceed the burst_interval. We adopt the 203 // total sampling time, bursts may also exceed the burst_interval. We adopt the
(...skipping 22 matching lines...) Expand all
207 226
208 if (was_stopped) 227 if (was_stopped)
209 return; 228 return;
210 } 229 }
211 } 230 }
212 231
213 void StackSamplingProfiler::SamplingThread::Stop() { 232 void StackSamplingProfiler::SamplingThread::Stop() {
214 stop_event_.Signal(); 233 stop_event_.Signal();
215 } 234 }
216 235
236 // static
237 void StackSamplingProfiler::SetProcessPhase(ProcessPhase phase) {
238 DCHECK_EQ(0, subtle::NoBarrier_Load(&process_phases_) & (1 << phase));
239 ChangeAtomicFlags(&process_phases_, 1 << phase, 0);
240 }
241
242 // static
243 void StackSamplingProfiler::RecordActivityBegin(ProcessActivity activity) {
244 ChangeAtomicFlags(&current_activities_, 1 << activity, 0);
245 }
246
247 // static
248 void StackSamplingProfiler::RecordActivityEnd(ProcessActivity activity) {
249 ChangeAtomicFlags(&current_activities_, 0, 1 << activity);
250 }
251
217 // StackSamplingProfiler ------------------------------------------------------ 252 // StackSamplingProfiler ------------------------------------------------------
218 253
254 volatile subtle::Atomic32 StackSamplingProfiler::process_phases_ = 0;
255 volatile subtle::Atomic32 StackSamplingProfiler::current_activities_ = 0;
256
219 StackSamplingProfiler::SamplingParams::SamplingParams() 257 StackSamplingProfiler::SamplingParams::SamplingParams()
220 : initial_delay(TimeDelta::FromMilliseconds(0)), 258 : initial_delay(TimeDelta::FromMilliseconds(0)),
221 bursts(1), 259 bursts(1),
222 burst_interval(TimeDelta::FromMilliseconds(10000)), 260 burst_interval(TimeDelta::FromMilliseconds(10000)),
223 samples_per_burst(300), 261 samples_per_burst(300),
224 sampling_interval(TimeDelta::FromMilliseconds(100)) { 262 sampling_interval(TimeDelta::FromMilliseconds(100)) {
225 } 263 }
226 264
227 StackSamplingProfiler::StackSamplingProfiler( 265 StackSamplingProfiler::StackSamplingProfiler(
228 PlatformThreadId thread_id, 266 PlatformThreadId thread_id,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 } 314 }
277 315
278 // StackSamplingProfiler::Frame global functions ------------------------------ 316 // StackSamplingProfiler::Frame global functions ------------------------------
279 317
280 bool operator==(const StackSamplingProfiler::Module& a, 318 bool operator==(const StackSamplingProfiler::Module& a,
281 const StackSamplingProfiler::Module& b) { 319 const StackSamplingProfiler::Module& b) {
282 return a.base_address == b.base_address && a.id == b.id && 320 return a.base_address == b.base_address && a.id == b.id &&
283 a.filename == b.filename; 321 a.filename == b.filename;
284 } 322 }
285 323
324 bool operator==(const StackSamplingProfiler::Sample& a,
325 const StackSamplingProfiler::Sample& b) {
326 return a.process_phases == b.process_phases &&
327 a.current_activities == b.current_activities && a.frames == b.frames;
328 }
329
330 bool operator!=(const StackSamplingProfiler::Sample& a,
331 const StackSamplingProfiler::Sample& b) {
332 return !(a == b);
333 }
334
335 bool operator<(const StackSamplingProfiler::Sample& a,
336 const StackSamplingProfiler::Sample& b) {
337 if (a.process_phases < b.process_phases)
338 return true;
339 if (a.process_phases > b.process_phases)
340 return false;
341
342 if (a.current_activities < b.current_activities)
343 return true;
344 if (a.current_activities > b.current_activities)
345 return false;
346
347 return a.frames < b.frames;
348 }
349
286 bool operator==(const StackSamplingProfiler::Frame &a, 350 bool operator==(const StackSamplingProfiler::Frame &a,
287 const StackSamplingProfiler::Frame &b) { 351 const StackSamplingProfiler::Frame &b) {
288 return a.instruction_pointer == b.instruction_pointer && 352 return a.instruction_pointer == b.instruction_pointer &&
289 a.module_index == b.module_index; 353 a.module_index == b.module_index;
290 } 354 }
291 355
292 bool operator<(const StackSamplingProfiler::Frame &a, 356 bool operator<(const StackSamplingProfiler::Frame &a,
293 const StackSamplingProfiler::Frame &b) { 357 const StackSamplingProfiler::Frame &b) {
294 return (a.module_index < b.module_index) || 358 return (a.module_index < b.module_index) ||
295 (a.module_index == b.module_index && 359 (a.module_index == b.module_index &&
296 a.instruction_pointer < b.instruction_pointer); 360 a.instruction_pointer < b.instruction_pointer);
297 } 361 }
298 362
299 } // namespace base 363 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698