OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/profiler/stack_sampling_profiler.h" | 5 #include "base/profiler/stack_sampling_profiler.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 void PerformCollectionTask(int id); | 243 void PerformCollectionTask(int id); |
244 void ShutdownTask(int add_events); | 244 void ShutdownTask(int add_events); |
245 | 245 |
246 // Updates the |next_sample_time| time based on configured parameters. | 246 // Updates the |next_sample_time| time based on configured parameters. |
247 // Returns true if there is a next sample or false if sampling is complete. | 247 // Returns true if there is a next sample or false if sampling is complete. |
248 bool UpdateNextSampleTime(CollectionContext* collection); | 248 bool UpdateNextSampleTime(CollectionContext* collection); |
249 | 249 |
250 // Thread: | 250 // Thread: |
251 void CleanUp() override; | 251 void CleanUp() override; |
252 | 252 |
| 253 // A stack-buffer used by the native sampler for its work. This buffer can |
| 254 // be re-used for multiple native sampler objects so long as the API calls |
| 255 // that take it are not called concurrently. |
| 256 std::unique_ptr<NativeStackSampler::StackBuffer> stack_buffer_; |
| 257 |
253 // A map of IDs to collection contexts. Because this class is a singleton | 258 // A map of IDs to collection contexts. Because this class is a singleton |
254 // that is never destroyed, context objects will never be destructed except | 259 // that is never destroyed, context objects will never be destructed except |
255 // by explicit action. Thus, it's acceptable to pass unretained pointers | 260 // by explicit action. Thus, it's acceptable to pass unretained pointers |
256 // to these objects when posting tasks. | 261 // to these objects when posting tasks. |
257 std::map<int, std::unique_ptr<CollectionContext>> active_collections_; | 262 std::map<int, std::unique_ptr<CollectionContext>> active_collections_; |
258 | 263 |
259 // State maintained about the current execution (or non-execution) of | 264 // State maintained about the current execution (or non-execution) of |
260 // the thread. This state must always be accessed while holding the | 265 // the thread. This state must always be accessed while holding the |
261 // lock. A copy of the task-runner is maintained here for use by any | 266 // lock. A copy of the task-runner is maintained here for use by any |
262 // calling thread; this is necessary because Thread's accessor for it is | 267 // calling thread; this is necessary because Thread's accessor for it is |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 DCHECK_NE(GetThreadId(), PlatformThread::CurrentId()); | 419 DCHECK_NE(GetThreadId(), PlatformThread::CurrentId()); |
415 return thread_execution_state_task_runner_; | 420 return thread_execution_state_task_runner_; |
416 } | 421 } |
417 | 422 |
418 if (thread_execution_state_ == EXITING) { | 423 if (thread_execution_state_ == EXITING) { |
419 // The previous instance has only been partially cleaned up. It is necessary | 424 // The previous instance has only been partially cleaned up. It is necessary |
420 // to call Stop() before Start(). | 425 // to call Stop() before Start(). |
421 Stop(); | 426 Stop(); |
422 } | 427 } |
423 | 428 |
| 429 DCHECK(!stack_buffer_); |
| 430 stack_buffer_ = NativeStackSampler::CreateStackBuffer(); |
| 431 |
424 // The thread is not running. Start it and get associated runner. The task- | 432 // The thread is not running. Start it and get associated runner. The task- |
425 // runner has to be saved for future use because though it can be used from | 433 // runner has to be saved for future use because though it can be used from |
426 // any thread, it can be acquired via task_runner() only on the created | 434 // any thread, it can be acquired via task_runner() only on the created |
427 // thread and the thread that creates it (i.e. this thread) for thread-safety | 435 // thread and the thread that creates it (i.e. this thread) for thread-safety |
428 // reasons which are alleviated in SamplingThread by gating access to it with | 436 // reasons which are alleviated in SamplingThread by gating access to it with |
429 // the |thread_execution_state_lock_|. | 437 // the |thread_execution_state_lock_|. |
430 Start(); | 438 Start(); |
431 thread_execution_state_ = RUNNING; | 439 thread_execution_state_ = RUNNING; |
432 thread_execution_state_task_runner_ = Thread::task_runner(); | 440 thread_execution_state_task_runner_ = Thread::task_runner(); |
433 | 441 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 profile.sampling_period = collection->params.sampling_interval; | 518 profile.sampling_period = collection->params.sampling_interval; |
511 collection->profile_start_time = Time::Now(); | 519 collection->profile_start_time = Time::Now(); |
512 collection->native_sampler->ProfileRecordingStarting(&profile.modules); | 520 collection->native_sampler->ProfileRecordingStarting(&profile.modules); |
513 } | 521 } |
514 | 522 |
515 // The currently active profile being captured. | 523 // The currently active profile being captured. |
516 CallStackProfile& profile = collection->profiles.back(); | 524 CallStackProfile& profile = collection->profiles.back(); |
517 | 525 |
518 // Record a single sample. | 526 // Record a single sample. |
519 profile.samples.push_back(Sample()); | 527 profile.samples.push_back(Sample()); |
520 collection->native_sampler->RecordStackSample(&profile.samples.back()); | 528 collection->native_sampler->RecordStackSample(stack_buffer_.get(), |
| 529 &profile.samples.back()); |
521 | 530 |
522 // If this is the last sample of a burst, record the total time. | 531 // If this is the last sample of a burst, record the total time. |
523 if (collection->sample == collection->params.samples_per_burst - 1) { | 532 if (collection->sample == collection->params.samples_per_burst - 1) { |
524 profile.profile_duration = Time::Now() - collection->profile_start_time; | 533 profile.profile_duration = Time::Now() - collection->profile_start_time; |
525 collection->native_sampler->ProfileRecordingStopped(); | 534 collection->native_sampler->ProfileRecordingStopped(stack_buffer_.get()); |
526 } | 535 } |
527 } | 536 } |
528 | 537 |
529 void StackSamplingProfiler::SamplingThread::ScheduleShutdownIfIdle() { | 538 void StackSamplingProfiler::SamplingThread::ScheduleShutdownIfIdle() { |
530 DCHECK_EQ(GetThreadId(), PlatformThread::CurrentId()); | 539 DCHECK_EQ(GetThreadId(), PlatformThread::CurrentId()); |
531 | 540 |
532 if (!active_collections_.empty()) | 541 if (!active_collections_.empty()) |
533 return; | 542 return; |
534 | 543 |
535 int add_events; | 544 int add_events; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 // (again) in order for Stop/Start to be called (again) should more work | 649 // (again) in order for Stop/Start to be called (again) should more work |
641 // come in. Holding the |thread_execution_state_lock_| ensures the necessary | 650 // come in. Holding the |thread_execution_state_lock_| ensures the necessary |
642 // happens-after with regard to this detach and future Thread API calls. | 651 // happens-after with regard to this detach and future Thread API calls. |
643 DetachFromSequence(); | 652 DetachFromSequence(); |
644 | 653 |
645 // Set the thread_state variable so the thread will be restarted when new | 654 // Set the thread_state variable so the thread will be restarted when new |
646 // work comes in. Remove the |thread_execution_state_task_runner_| to avoid | 655 // work comes in. Remove the |thread_execution_state_task_runner_| to avoid |
647 // confusion. | 656 // confusion. |
648 thread_execution_state_ = EXITING; | 657 thread_execution_state_ = EXITING; |
649 thread_execution_state_task_runner_ = nullptr; | 658 thread_execution_state_task_runner_ = nullptr; |
| 659 stack_buffer_.reset(); |
650 } | 660 } |
651 | 661 |
652 bool StackSamplingProfiler::SamplingThread::UpdateNextSampleTime( | 662 bool StackSamplingProfiler::SamplingThread::UpdateNextSampleTime( |
653 CollectionContext* collection) { | 663 CollectionContext* collection) { |
654 // This will keep a consistent average interval between samples but will | 664 // This will keep a consistent average interval between samples but will |
655 // result in constant series of acquisitions, thus nearly locking out the | 665 // result in constant series of acquisitions, thus nearly locking out the |
656 // target thread, if the interval is smaller than the time it takes to | 666 // target thread, if the interval is smaller than the time it takes to |
657 // actually acquire the sample. Anything sampling that quickly is going | 667 // actually acquire the sample. Anything sampling that quickly is going |
658 // to be a problem anyway so don't worry about it. | 668 // to be a problem anyway so don't worry about it. |
659 if (++collection->sample < collection->params.samples_per_burst) { | 669 if (++collection->sample < collection->params.samples_per_burst) { |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
833 } | 843 } |
834 | 844 |
835 bool operator<(const StackSamplingProfiler::Frame &a, | 845 bool operator<(const StackSamplingProfiler::Frame &a, |
836 const StackSamplingProfiler::Frame &b) { | 846 const StackSamplingProfiler::Frame &b) { |
837 return (a.module_index < b.module_index) || | 847 return (a.module_index < b.module_index) || |
838 (a.module_index == b.module_index && | 848 (a.module_index == b.module_index && |
839 a.instruction_pointer < b.instruction_pointer); | 849 a.instruction_pointer < b.instruction_pointer); |
840 } | 850 } |
841 | 851 |
842 } // namespace base | 852 } // namespace base |
OLD | NEW |