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

Unified Diff: base/profiler/stack_sampling_profiler.cc

Issue 2927593002: Make stack sampling profiler sample beyond startup. (Closed)
Patch Set: Add TODO. Move sampling_profiler_params_ to chrome_browser_main. Created 3 years, 5 months 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 39d665cb24f77064097330137c0818142ed4004c..a9b55973f4fc2dff03ac1d446ce54ff2929b00aa 100644
--- a/base/profiler/stack_sampling_profiler.cc
+++ b/base/profiler/stack_sampling_profiler.cc
@@ -31,7 +31,7 @@ namespace {
// This value is used when there is no collection in progress and thus no ID
// for referencing the active collection to the SamplingThread.
-const int NULL_COLLECTION_ID = -1;
+const int NULL_PROFILER_ID = -1;
void ChangeAtomicFlags(subtle::Atomic32* flags,
subtle::Atomic32 set,
@@ -139,12 +139,13 @@ class StackSamplingProfiler::SamplingThread : public Thread {
};
struct CollectionContext {
- CollectionContext(PlatformThreadId target,
+ CollectionContext(int profiler_id,
+ PlatformThreadId target,
const SamplingParams& params,
const CompletedCallback& callback,
WaitableEvent* finished,
std::unique_ptr<NativeStackSampler> sampler)
- : collection_id(next_collection_id_.GetNext()),
+ : profiler_id(profiler_id),
target(target),
params(params),
callback(callback),
@@ -152,9 +153,9 @@ class StackSamplingProfiler::SamplingThread : public Thread {
native_sampler(std::move(sampler)) {}
~CollectionContext() {}
- // An identifier for this collection, used to uniquely identify it to
- // outside interests.
- const int collection_id;
+ // An identifier for the profiler associated with this collection, used to
+ // uniquely identify the collection to outside interests.
+ const int profiler_id;
const PlatformThreadId target; // ID of The thread being sampled.
const SamplingParams params; // Information about how to sample.
@@ -177,8 +178,8 @@ class StackSamplingProfiler::SamplingThread : public Thread {
// The collected stack samples. The active profile is always at the back().
CallStackProfiles profiles;
- private:
- static StaticAtomicSequenceNumber next_collection_id_;
+ // Sequence number for generating new profiler ids.
+ static StaticAtomicSequenceNumber next_profiler_id;
};
// Gets the single instance of this class.
@@ -228,8 +229,9 @@ class StackSamplingProfiler::SamplingThread : public Thread {
// Get task runner that is usable from the sampling thread itself.
scoped_refptr<SingleThreadTaskRunner> GetTaskRunnerOnSamplingThread();
- // Finishes a collection and reports collected data via callback.
- void FinishCollection(CollectionContext* collection);
+ // Finishes a collection and reports collected data via callback. Returns
+ // the new collection params, if a new collection should be started.
+ Optional<SamplingParams> FinishCollection(CollectionContext* collection);
// Records a single sample of a collection.
void RecordSample(CollectionContext* collection);
@@ -361,8 +363,8 @@ void StackSamplingProfiler::SamplingThread::TestAPI::ShutdownTaskAndSignalEvent(
event->Signal();
}
-StaticAtomicSequenceNumber StackSamplingProfiler::SamplingThread::
- CollectionContext::next_collection_id_;
+StaticAtomicSequenceNumber
+ StackSamplingProfiler::SamplingThread::CollectionContext::next_profiler_id;
StackSamplingProfiler::SamplingThread::SamplingThread()
: Thread("StackSamplingProfiler") {}
@@ -378,7 +380,7 @@ int StackSamplingProfiler::SamplingThread::Add(
std::unique_ptr<CollectionContext> collection) {
// This is not to be run on the sampling thread.
- int id = collection->collection_id;
+ int id = collection->profiler_id;
scoped_refptr<SingleThreadTaskRunner> task_runner =
GetOrCreateTaskRunnerForAdd();
@@ -475,7 +477,8 @@ StackSamplingProfiler::SamplingThread::GetTaskRunnerOnSamplingThread() {
return Thread::task_runner();
}
-void StackSamplingProfiler::SamplingThread::FinishCollection(
+Optional<StackSamplingProfiler::SamplingParams>
+StackSamplingProfiler::SamplingThread::FinishCollection(
CollectionContext* collection) {
DCHECK_EQ(GetThreadId(), PlatformThread::CurrentId());
@@ -495,16 +498,13 @@ void StackSamplingProfiler::SamplingThread::FinishCollection(
CallStackProfiles profiles = std::move(collection->profiles);
WaitableEvent* finished = collection->finished;
- // Remove this collection from the map of known ones. The |collection|
- // parameter is invalid after this point.
- size_t count = active_collections_.erase(collection->collection_id);
Mike Wittman 2017/07/07 21:01:11 The test code depends on the finished event below
Alexei Svitkine (slow) 2017/07/10 22:05:37 Ah, this wasn't obvious. Change to still do it her
Mike Wittman 2017/07/10 22:31:25 The callback is also used as a synchronization poi
Alexei Svitkine (slow) 2017/07/11 18:27:05 I see. So this required reorganizing things a bit
- DCHECK_EQ(1U, count);
-
// Run the associated callback, passing the collected profiles.
- callback.Run(std::move(profiles));
+ Optional<SamplingParams> new_params = callback.Run(std::move(profiles));
// Signal that this collection is finished.
finished->Signal();
+
+ return new_params;
}
void StackSamplingProfiler::SamplingThread::RecordSample(
@@ -561,16 +561,16 @@ void StackSamplingProfiler::SamplingThread::AddCollectionTask(
std::unique_ptr<CollectionContext> collection) {
DCHECK_EQ(GetThreadId(), PlatformThread::CurrentId());
- const int collection_id = collection->collection_id;
+ const int profiler_id = collection->profiler_id;
const TimeDelta initial_delay = collection->params.initial_delay;
active_collections_.insert(
- std::make_pair(collection_id, std::move(collection)));
+ std::make_pair(profiler_id, std::move(collection)));
GetTaskRunnerOnSamplingThread()->PostDelayedTask(
FROM_HERE,
BindOnce(&SamplingThread::PerformCollectionTask, Unretained(this),
- collection_id),
+ profiler_id),
initial_delay);
// Another increment of "add events" serves to invalidate any pending
@@ -589,7 +589,14 @@ void StackSamplingProfiler::SamplingThread::RemoveCollectionTask(int id) {
if (found == active_collections_.end())
return;
- FinishCollection(found->second.get());
+ auto* collection = found->second.get();
+ FinishCollection(collection);
+
+ // Remove this collection from the map of known ones. After this,
+ // |collection| will be invalid.
+ size_t count = active_collections_.erase(collection->profiler_id);
+ DCHECK_EQ(1U, count);
+
ScheduleShutdownIfIdle();
}
@@ -612,19 +619,41 @@ void StackSamplingProfiler::SamplingThread::PerformCollectionTask(int id) {
RecordSample(collection);
// Update the time of the next sample recording.
- if (UpdateNextSampleTime(collection)) {
- bool success = GetTaskRunnerOnSamplingThread()->PostDelayedTask(
- FROM_HERE,
- BindOnce(&SamplingThread::PerformCollectionTask, Unretained(this), id),
- std::max(collection->next_sample_time - Time::Now(), TimeDelta()));
- DCHECK(success);
- } else {
- // All capturing has completed so finish the collection. By not re-adding
- // it to the task queue, the collection will "expire" (i.e. no further work
- // will be done). The |collection| variable will be invalid after this call.
- FinishCollection(collection);
- ScheduleShutdownIfIdle();
+ const bool collection_finished = !UpdateNextSampleTime(collection);
+ if (collection_finished) {
+ // All capturing has completed so finish the collection. If no new params
+ // are returned, a new collection should not be started.
+ Optional<SamplingParams> new_params = FinishCollection(collection);
+ if (!new_params.has_value()) {
+ // Remove this collection from the map of known ones. After this,
+ // |collection| will be invalid.
+ size_t count = active_collections_.erase(collection->profiler_id);
+ DCHECK_EQ(1U, count);
+
+ // By not adding it to the task queue, the collection will "expire" (i.e.
+ // no further work will be done).
+ ScheduleShutdownIfIdle();
+ return;
+ }
+
+ // Restart the collection with the new params. Keep the same collection
+ // id so the Stop() operation continues to work.
+ auto new_collection = MakeUnique<SamplingThread::CollectionContext>(
+ collection->profiler_id, collection->target, new_params.value(),
+ collection->callback, collection->finished,
+ std::move(collection->native_sampler));
+ new_collection->next_sample_time =
+ Time::Now() + collection->params.initial_delay;
+ // Replace |collection| in the map by |new_collection|. After this,
+ // |collection| will be invalid.
+ found->second = std::move(new_collection);
}
+
+ bool success = GetTaskRunnerOnSamplingThread()->PostDelayedTask(
+ FROM_HERE,
+ BindOnce(&SamplingThread::PerformCollectionTask, Unretained(this), id),
+ std::max(collection->next_sample_time - Time::Now(), TimeDelta()));
+ DCHECK(success);
}
void StackSamplingProfiler::SamplingThread::ShutdownTask(int add_events) {
@@ -744,7 +773,7 @@ StackSamplingProfiler::StackSamplingProfiler(
// and "manual" so that it can be waited in multiple places.
profiling_inactive_(WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::SIGNALED),
- collection_id_(NULL_COLLECTION_ID),
+ profiler_id_(NULL_PROFILER_ID),
test_delegate_(test_delegate) {}
StackSamplingProfiler::~StackSamplingProfiler() {
@@ -781,17 +810,18 @@ void StackSamplingProfiler::Start() {
profiling_inactive_.Wait();
profiling_inactive_.Reset();
- DCHECK_EQ(NULL_COLLECTION_ID, collection_id_);
- collection_id_ = SamplingThread::GetInstance()->Add(
+ DCHECK_EQ(NULL_PROFILER_ID, profiler_id_);
+ profiler_id_ = SamplingThread::GetInstance()->Add(
MakeUnique<SamplingThread::CollectionContext>(
+ SamplingThread::CollectionContext::next_profiler_id.GetNext(),
thread_id_, params_, completed_callback_, &profiling_inactive_,
std::move(native_sampler)));
- DCHECK_NE(NULL_COLLECTION_ID, collection_id_);
+ DCHECK_NE(NULL_PROFILER_ID, profiler_id_);
}
void StackSamplingProfiler::Stop() {
- SamplingThread::GetInstance()->Remove(collection_id_);
- collection_id_ = NULL_COLLECTION_ID;
+ SamplingThread::GetInstance()->Remove(profiler_id_);
+ profiler_id_ = NULL_PROFILER_ID;
}
// static

Powered by Google App Engine
This is Rietveld 408576698