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

Unified Diff: base/profiler/stack_sampling_profiler.cc

Issue 2444143002: Add process lifetime annotations to stack samples. (Closed)
Patch Set: addressed review comments and finished converting tests 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 side-by-side diff with in-line comments
Download patch
Index: base/profiler/stack_sampling_profiler.cc
diff --git a/base/profiler/stack_sampling_profiler.cc b/base/profiler/stack_sampling_profiler.cc
index e25440f80c56b32896b0f018b38e2514086f933d..36474a491548be71a82725637516649fa8be4a95 100644
--- a/base/profiler/stack_sampling_profiler.cc
+++ b/base/profiler/stack_sampling_profiler.cc
@@ -82,6 +82,22 @@ void AsyncRunner::RunCallbackAndDeleteInstance(
task_runner->DeleteSoon(FROM_HERE, object_to_be_deleted.release());
}
+void ChangeAtomicFlags(subtle::Atomic32* flags,
+ 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 ----------------------------------------------
@@ -106,6 +122,21 @@ StackSamplingProfiler::Frame::Frame()
: instruction_pointer(0), module_index(kUnknownModuleIndex) {
}
+// StackSamplingProfiler::Sample ----------------------------------------------
+
+StackSamplingProfiler::Sample::Sample() {}
+
+StackSamplingProfiler::Sample::Sample(const Sample& sample) = default;
+
+StackSamplingProfiler::Sample::~Sample() {}
+
+StackSamplingProfiler::Sample::Sample(const Frame& frame) {
+ frames.push_back(std::move(frame));
+}
+
+StackSamplingProfiler::Sample::Sample(const std::vector<Frame>& frames)
+ : frames(frames) {}
+
// StackSamplingProfiler::CallStackProfile ------------------------------------
StackSamplingProfiler::CallStackProfile::CallStackProfile() {}
@@ -184,7 +215,8 @@ void StackSamplingProfiler::SamplingThread::CollectProfile(
}
ElapsedTimer sample_timer;
profile->samples.push_back(Sample());
- native_sampler_->RecordStackSample(&profile->samples.back());
+ Sample& sample = profile->samples.back();
+ native_sampler_->RecordStackSample(&sample);
Alexei Svitkine (slow) 2016/11/16 19:10:23 Nit: Remove this change since it doesn't seem nece
bcwhite 2016/11/16 23:10:48 Done.
previous_elapsed_sample_time = sample_timer.Elapsed();
}
@@ -229,6 +261,8 @@ void StackSamplingProfiler::SamplingThread::Stop() {
// StackSamplingProfiler ------------------------------------------------------
+subtle::Atomic32 StackSamplingProfiler::process_phases_ = 0;
+
StackSamplingProfiler::SamplingParams::SamplingParams()
: initial_delay(TimeDelta::FromMilliseconds(0)),
bursts(1),
@@ -272,7 +306,8 @@ void StackSamplingProfiler::Start() {
return;
std::unique_ptr<NativeStackSampler> native_sampler =
- NativeStackSampler::Create(thread_id_, test_delegate_);
+ NativeStackSampler::Create(thread_id_, &RecordAnnotations,
+ test_delegate_);
if (!native_sampler)
return;
@@ -288,6 +323,27 @@ void StackSamplingProfiler::Stop() {
sampling_thread_->Stop();
}
+// static
+void StackSamplingProfiler::SetProcessPhase(int phase) {
+ DCHECK_LE(0, phase);
+ DCHECK_GT(static_cast<int>(sizeof(process_phases_) * 8), phase);
+ DCHECK_EQ(0, subtle::NoBarrier_Load(&process_phases_) & (1 << phase));
+ ChangeAtomicFlags(&process_phases_, 1 << phase, 0);
+}
+
+// static
+void StackSamplingProfiler::ResetAnnotationsForTesting() {
+ subtle::NoBarrier_Store(&process_phases_, 0u);
+}
+
+// The code inside this method must not do anything that could acquire a mutex,
Alexei Svitkine (slow) 2016/11/16 19:10:24 Nit: Move this comment inside the method.
bcwhite 2016/11/16 23:10:48 Done.
+// including allocating memory (which includes LOG messages) because that mutex
+// could be held by a stopped thread, thus resulting in deadlock.
+// static
+void StackSamplingProfiler::RecordAnnotations(Sample* sample) {
+ sample->process_phases = subtle::NoBarrier_Load(&process_phases_);
+}
+
// StackSamplingProfiler::Frame global functions ------------------------------
bool operator==(const StackSamplingProfiler::Module& a,
@@ -296,6 +352,26 @@ 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.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;
+
+ return a.frames < b.frames;
+}
+
bool operator==(const StackSamplingProfiler::Frame &a,
const StackSamplingProfiler::Frame &b) {
return a.instruction_pointer == b.instruction_pointer &&

Powered by Google App Engine
This is Rietveld 408576698