Chromium Code Reviews| Index: base/profiler/stack_sampling_profiler.cc |
| diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc |
| index 538368bd23f6fd63d25dfefa6e6ea68f5a785208..dae1ee7df32db63e48195a6460c4f9c670b4e91c 100644 |
| --- a/base/profiler/stack_sampling_profiler.cc |
| +++ b/base/profiler/stack_sampling_profiler.cc |
| @@ -81,6 +81,22 @@ void AsyncRunner::RunCallbackAndDeleteInstance( |
| task_runner->DeleteSoon(FROM_HERE, object_to_be_deleted.release()); |
| } |
| +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.
|
| + subtle::Atomic32 set, |
| + subtle::Atomic32 clear) { |
| + DCHECK(set != 0 || clear != 0); |
| + DCHECK_EQ(0, set & clear); |
| + |
| + subtle::Atomic32 bits = subtle::NoBarrier_Load(flags); |
| + while (true) { |
| + subtle::Atomic32 existing = |
| + subtle::NoBarrier_CompareAndSwap(flags, bits, (bits | set) & ~clear); |
| + if (existing == bits) |
| + break; |
| + bits = existing; |
| + } |
| +} |
| + |
| } // namespace |
| // StackSamplingProfiler::Module ---------------------------------------------- |
| @@ -171,7 +187,10 @@ void StackSamplingProfiler::SamplingThread::CollectProfile( |
| } |
| ElapsedTimer sample_timer; |
| profile->samples.push_back(Sample()); |
| - native_sampler_->RecordStackSample(&profile->samples.back()); |
| + Sample& sample = profile->samples.back(); |
| + sample.process_phases = subtle::NoBarrier_Load(&process_phases_); |
| + sample.current_activities = subtle::NoBarrier_Load(¤t_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
|
| + native_sampler_->RecordStackSample(&sample); |
| previous_elapsed_sample_time = sample_timer.Elapsed(); |
| } |
| @@ -214,8 +233,27 @@ void StackSamplingProfiler::SamplingThread::Stop() { |
| stop_event_.Signal(); |
| } |
| +// static |
| +void StackSamplingProfiler::SetProcessPhase(ProcessPhase phase) { |
| + DCHECK_EQ(0, subtle::NoBarrier_Load(&process_phases_) & (1 << phase)); |
| + ChangeAtomicFlags(&process_phases_, 1 << phase, 0); |
| +} |
| + |
| +// static |
| +void StackSamplingProfiler::RecordActivityBegin(ProcessActivity activity) { |
| + ChangeAtomicFlags(¤t_activities_, 1 << activity, 0); |
| +} |
| + |
| +// static |
| +void StackSamplingProfiler::RecordActivityEnd(ProcessActivity activity) { |
| + ChangeAtomicFlags(¤t_activities_, 0, 1 << activity); |
| +} |
| + |
| // StackSamplingProfiler ------------------------------------------------------ |
| +volatile subtle::Atomic32 StackSamplingProfiler::process_phases_ = 0; |
| +volatile subtle::Atomic32 StackSamplingProfiler::current_activities_ = 0; |
| + |
| StackSamplingProfiler::SamplingParams::SamplingParams() |
| : initial_delay(TimeDelta::FromMilliseconds(0)), |
| bursts(1), |
| @@ -283,6 +321,32 @@ bool operator==(const StackSamplingProfiler::Module& a, |
| a.filename == b.filename; |
| } |
| +bool operator==(const StackSamplingProfiler::Sample& a, |
| + const StackSamplingProfiler::Sample& b) { |
| + return a.process_phases == b.process_phases && |
| + a.current_activities == b.current_activities && a.frames == b.frames; |
| +} |
| + |
| +bool operator!=(const StackSamplingProfiler::Sample& a, |
| + const StackSamplingProfiler::Sample& b) { |
| + return !(a == b); |
| +} |
| + |
| +bool operator<(const StackSamplingProfiler::Sample& a, |
| + const StackSamplingProfiler::Sample& b) { |
| + if (a.process_phases < b.process_phases) |
| + return true; |
| + if (a.process_phases > b.process_phases) |
| + return false; |
| + |
| + if (a.current_activities < b.current_activities) |
| + return true; |
| + if (a.current_activities > b.current_activities) |
| + return false; |
| + |
| + return a.frames < b.frames; |
| +} |
| + |
| bool operator==(const StackSamplingProfiler::Frame &a, |
| const StackSamplingProfiler::Frame &b) { |
| return a.instruction_pointer == b.instruction_pointer && |