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

Unified Diff: base/profiler/stack_sampling_profiler.cc

Issue 2927593002: Make stack sampling profiler sample beyond startup. (Closed)
Patch Set: Address comments. 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..ab2268be5eb22cd7bbaa3556afa33a4a4e74e26b 100644
--- a/base/profiler/stack_sampling_profiler.cc
+++ b/base/profiler/stack_sampling_profiler.cc
@@ -139,12 +139,13 @@ class StackSamplingProfiler::SamplingThread : public Thread {
};
struct CollectionContext {
- CollectionContext(PlatformThreadId target,
+ CollectionContext(int collection_id,
+ PlatformThreadId target,
const SamplingParams& params,
const CompletedCallback& callback,
WaitableEvent* finished,
std::unique_ptr<NativeStackSampler> sampler)
- : collection_id(next_collection_id_.GetNext()),
+ : collection_id(collection_id),
target(target),
params(params),
callback(callback),
@@ -177,7 +178,6 @@ 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_;
Mike Wittman 2017/07/06 17:25:53 nit: drop trailing underscore
Alexei Svitkine (slow) 2017/07/06 19:36:26 Done.
};
@@ -228,8 +228,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);
@@ -475,7 +476,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 +497,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);
- 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(
@@ -589,7 +588,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->collection_id);
+ DCHECK_EQ(1U, count);
+
ScheduleShutdownIfIdle();
}
@@ -612,19 +618,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->collection_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->collection_id, collection->target, new_params.value(),
+ collection->callback, collection->finished,
+ std::move(collection->native_sampler));
+ new_collection->next_sample_time =
Mike Wittman 2017/07/06 17:25:52 Can we reuse the logic in AddCollectionTask for re
Alexei Svitkine (slow) 2017/07/06 19:36:25 The way it's structured right now, it re-uses the
Mike Wittman 2017/07/06 22:14:01 I was thinking that we could remove the old collec
+ 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) {
@@ -784,6 +812,7 @@ void StackSamplingProfiler::Start() {
DCHECK_EQ(NULL_COLLECTION_ID, collection_id_);
collection_id_ = SamplingThread::GetInstance()->Add(
MakeUnique<SamplingThread::CollectionContext>(
+ SamplingThread::CollectionContext::next_collection_id_.GetNext(),
thread_id_, params_, completed_callback_, &profiling_inactive_,
std::move(native_sampler)));
DCHECK_NE(NULL_COLLECTION_ID, collection_id_);

Powered by Google App Engine
This is Rietveld 408576698