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_); |