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 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) { |