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

Side by Side Diff: base/profiler/stack_sampling_profiler.cc

Issue 2601633002: Use a common buffer across all instances for stack-copy. (Closed)
Patch Set: addressed review comments by wittman Created 3 years, 7 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 unified diff | Download patch
« no previous file with comments | « base/profiler/native_stack_sampler_win.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « base/profiler/native_stack_sampler_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698