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..879323094b8f6202bda1551fbfbdc72775dd5b91 100644 |
--- a/base/profiler/stack_sampling_profiler.cc |
+++ b/base/profiler/stack_sampling_profiler.cc |
@@ -157,7 +157,11 @@ class StackSamplingProfiler::SamplingThread : public Thread { |
const int collection_id; |
const PlatformThreadId target; // ID of The thread being sampled. |
- const SamplingParams params; // Information about how to sample. |
+ |
+ // Information about how to sample. Not const because they can be updated |
+ // upon collection completion by |callback|. |
+ SamplingParams params; |
+ |
const CompletedCallback callback; // Callback made when sampling complete. |
WaitableEvent* const finished; // Signaled when all sampling complete. |
@@ -228,8 +232,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 |
+ // whether collection should be restarted per the callback. |
+ bool FinishCollection(CollectionContext* collection); |
// Records a single sample of a collection. |
void RecordSample(CollectionContext* collection); |
@@ -475,7 +480,7 @@ StackSamplingProfiler::SamplingThread::GetTaskRunnerOnSamplingThread() { |
return Thread::task_runner(); |
} |
-void StackSamplingProfiler::SamplingThread::FinishCollection( |
+bool StackSamplingProfiler::SamplingThread::FinishCollection( |
CollectionContext* collection) { |
DCHECK_EQ(GetThreadId(), PlatformThread::CurrentId()); |
@@ -495,16 +500,14 @@ 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)); |
+ bool restart_collection = |
+ callback.Run(std::move(profiles), &collection->params); |
// Signal that this collection is finished. |
finished->Signal(); |
+ |
+ return restart_collection; |
} |
void StackSamplingProfiler::SamplingThread::RecordSample( |
@@ -589,7 +592,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. The |collection| |
+ // parameter is invalid after this point. |
+ size_t count = active_collections_.erase(collection->collection_id); |
+ DCHECK_EQ(1U, count); |
+ |
ScheduleShutdownIfIdle(); |
} |
@@ -612,19 +622,37 @@ 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); |
+ bool collection_finished = !UpdateNextSampleTime(collection); |
+ if (collection_finished) { |
+ // All capturing has completed so finish the collection. |
+ collection_finished = !FinishCollection(collection); |
+ if (!collection_finished) { |
+ // Attempt to restart the collection with the new params. |
+ collection->next_sample_time = |
Mike Wittman
2017/07/01 02:44:06
I'd prefer to create a new CollectionContext and s
Alexei Svitkine (slow)
2017/07/06 15:51:09
Done.
|
+ Time::Now() + collection->params.initial_delay; |
+ collection->burst = 0; |
+ collection->sample = 0; |
+ } |
+ } |
+ |
+ if (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); |
+ |
+ // By not 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. |
ScheduleShutdownIfIdle(); |
+ return; |
} |
+ |
+ 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) { |