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

Side by Side Diff: base/trace_event/memory_dump_manager.cc

Issue 1995573003: [tracing] Introduce BACKGROUND mode in MemoryInfra (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use nullptr to mark end. Created 4 years, 6 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
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/trace_event/memory_dump_manager.h" 5 #include "base/trace_event/memory_dump_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/atomic_sequence_num.h" 10 #include "base/atomic_sequence_num.h"
11 #include "base/base_switches.h" 11 #include "base/base_switches.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
14 #include "base/debug/debugging_flags.h" 14 #include "base/debug/debugging_flags.h"
15 #include "base/debug/stack_trace.h" 15 #include "base/debug/stack_trace.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/threading/thread.h" 17 #include "base/threading/thread.h"
18 #include "base/threading/thread_task_runner_handle.h" 18 #include "base/threading/thread_task_runner_handle.h"
19 #include "base/timer/timer.h"
19 #include "base/trace_event/heap_profiler.h" 20 #include "base/trace_event/heap_profiler.h"
20 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" 21 #include "base/trace_event/heap_profiler_allocation_context_tracker.h"
21 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h" 22 #include "base/trace_event/heap_profiler_stack_frame_deduplicator.h"
22 #include "base/trace_event/heap_profiler_type_name_deduplicator.h" 23 #include "base/trace_event/heap_profiler_type_name_deduplicator.h"
23 #include "base/trace_event/malloc_dump_provider.h" 24 #include "base/trace_event/malloc_dump_provider.h"
24 #include "base/trace_event/memory_dump_provider.h" 25 #include "base/trace_event/memory_dump_provider.h"
25 #include "base/trace_event/memory_dump_session_state.h" 26 #include "base/trace_event/memory_dump_session_state.h"
26 #include "base/trace_event/process_memory_dump.h" 27 #include "base/trace_event/process_memory_dump.h"
27 #include "base/trace_event/trace_event.h" 28 #include "base/trace_event/trace_event.h"
28 #include "base/trace_event/trace_event_argument.h" 29 #include "base/trace_event/trace_event_argument.h"
(...skipping 10 matching lines...) Expand all
39 namespace base { 40 namespace base {
40 namespace trace_event { 41 namespace trace_event {
41 42
42 namespace { 43 namespace {
43 44
44 const int kTraceEventNumArgs = 1; 45 const int kTraceEventNumArgs = 1;
45 const char* kTraceEventArgNames[] = {"dumps"}; 46 const char* kTraceEventArgNames[] = {"dumps"};
46 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE}; 47 const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE};
47 48
48 StaticAtomicSequenceNumber g_next_guid; 49 StaticAtomicSequenceNumber g_next_guid;
49 uint32_t g_periodic_dumps_count = 0;
50 uint32_t g_heavy_dumps_rate = 0;
51 MemoryDumpManager* g_instance_for_testing = nullptr; 50 MemoryDumpManager* g_instance_for_testing = nullptr;
52 51
53 void RequestPeriodicGlobalDump() { 52 // The names of dump providers whitelisted for background tracing. Dump
54 MemoryDumpLevelOfDetail level_of_detail; 53 // providers can be added here only if the background mode dump has very
55 if (g_heavy_dumps_rate == 0) { 54 // less performance and memory overhead.
56 level_of_detail = MemoryDumpLevelOfDetail::LIGHT; 55 const char* const kDumpProviderWhitelist[] = {
57 } else { 56 // TODO(ssid): Fill this list with dump provider names which support
58 level_of_detail = g_periodic_dumps_count == 0 57 // background mode, crbug.com/613198.
59 ? MemoryDumpLevelOfDetail::DETAILED 58 nullptr, // End of list marker.
60 : MemoryDumpLevelOfDetail::LIGHT; 59 };
61
62 if (++g_periodic_dumps_count == g_heavy_dumps_rate)
63 g_periodic_dumps_count = 0;
64 }
65
66 MemoryDumpManager::GetInstance()->RequestGlobalDump(
67 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail);
68 }
69 60
70 // Callback wrapper to hook upon the completion of RequestGlobalDump() and 61 // Callback wrapper to hook upon the completion of RequestGlobalDump() and
71 // inject trace markers. 62 // inject trace markers.
72 void OnGlobalDumpDone(MemoryDumpCallback wrapped_callback, 63 void OnGlobalDumpDone(MemoryDumpCallback wrapped_callback,
73 uint64_t dump_guid, 64 uint64_t dump_guid,
74 bool success) { 65 bool success) {
75 TRACE_EVENT_NESTABLE_ASYNC_END1( 66 TRACE_EVENT_NESTABLE_ASYNC_END1(
76 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump", 67 MemoryDumpManager::kTraceCategory, "GlobalMemoryDump",
77 TRACE_ID_MANGLE(dump_guid), "success", success); 68 TRACE_ID_MANGLE(dump_guid), "success", success);
78 69
(...skipping 23 matching lines...) Expand all
102 void EstimateTraceMemoryOverhead( 93 void EstimateTraceMemoryOverhead(
103 TraceEventMemoryOverhead* overhead) override { 94 TraceEventMemoryOverhead* overhead) override {
104 return (session_state.get()->*getter_function)() 95 return (session_state.get()->*getter_function)()
105 ->EstimateTraceMemoryOverhead(overhead); 96 ->EstimateTraceMemoryOverhead(overhead);
106 } 97 }
107 98
108 scoped_refptr<MemoryDumpSessionState> session_state; 99 scoped_refptr<MemoryDumpSessionState> session_state;
109 GetterFunctPtr const getter_function; 100 GetterFunctPtr const getter_function;
110 }; 101 };
111 102
103 // Checks if the name is in the given |list|. Last element of the list should be
104 // an empty string.
105 bool IsNameInList(const char* name, const char* const* list) {
106 for (size_t i = 0; list[i] != nullptr; ++i) {
107 if (strcmp(name, list[i]) == 0)
108 return true;
109 }
110 return false;
111 }
112
112 } // namespace 113 } // namespace
113 114
114 // static 115 // static
115 const char* const MemoryDumpManager::kTraceCategory = 116 const char* const MemoryDumpManager::kTraceCategory =
116 TRACE_DISABLED_BY_DEFAULT("memory-infra"); 117 TRACE_DISABLED_BY_DEFAULT("memory-infra");
117 118
118 // static 119 // static
119 const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3; 120 const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3;
120 121
121 // static 122 // static
(...skipping 20 matching lines...) Expand all
142 143
143 // static 144 // static
144 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) { 145 void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) {
145 g_instance_for_testing = instance; 146 g_instance_for_testing = instance;
146 } 147 }
147 148
148 MemoryDumpManager::MemoryDumpManager() 149 MemoryDumpManager::MemoryDumpManager()
149 : delegate_(nullptr), 150 : delegate_(nullptr),
150 is_coordinator_(false), 151 is_coordinator_(false),
151 memory_tracing_enabled_(0), 152 memory_tracing_enabled_(0),
153 dump_provider_whitelist_(kDumpProviderWhitelist),
152 tracing_process_id_(kInvalidTracingProcessId), 154 tracing_process_id_(kInvalidTracingProcessId),
153 dumper_registrations_ignored_for_testing_(false), 155 dumper_registrations_ignored_for_testing_(false),
154 heap_profiling_enabled_(false) { 156 heap_profiling_enabled_(false) {
155 g_next_guid.GetNext(); // Make sure that first guid is not zero. 157 g_next_guid.GetNext(); // Make sure that first guid is not zero.
156 158
157 // At this point the command line may not be initialized but we try to 159 // At this point the command line may not be initialized but we try to
158 // enable the heap profiler to capture allocations as soon as possible. 160 // enable the heap profiler to capture allocations as soon as possible.
159 EnableHeapProfilingIfNeeded(); 161 EnableHeapProfilingIfNeeded();
160 } 162 }
161 163
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 } 267 }
266 268
267 void MemoryDumpManager::RegisterDumpProviderInternal( 269 void MemoryDumpManager::RegisterDumpProviderInternal(
268 MemoryDumpProvider* mdp, 270 MemoryDumpProvider* mdp,
269 const char* name, 271 const char* name,
270 scoped_refptr<SequencedTaskRunner> task_runner, 272 scoped_refptr<SequencedTaskRunner> task_runner,
271 const MemoryDumpProvider::Options& options) { 273 const MemoryDumpProvider::Options& options) {
272 if (dumper_registrations_ignored_for_testing_) 274 if (dumper_registrations_ignored_for_testing_)
273 return; 275 return;
274 276
277 bool whitelisted_for_background_mode =
278 IsNameInList(name, dump_provider_whitelist_);
275 scoped_refptr<MemoryDumpProviderInfo> mdpinfo = 279 scoped_refptr<MemoryDumpProviderInfo> mdpinfo =
276 new MemoryDumpProviderInfo(mdp, name, std::move(task_runner), options); 280 new MemoryDumpProviderInfo(mdp, name, std::move(task_runner), options,
281 whitelisted_for_background_mode);
277 282
278 { 283 {
279 AutoLock lock(lock_); 284 AutoLock lock(lock_);
280 bool already_registered = !dump_providers_.insert(mdpinfo).second; 285 bool already_registered = !dump_providers_.insert(mdpinfo).second;
281 // This actually happens in some tests which don't have a clean tear-down 286 // This actually happens in some tests which don't have a clean tear-down
282 // path for RenderThreadImpl::Init(). 287 // path for RenderThreadImpl::Init().
283 if (already_registered) 288 if (already_registered)
284 return; 289 return;
285 } 290 }
286 291
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 pmd_async_state->pending_dump_providers.clear(); 447 pmd_async_state->pending_dump_providers.clear();
443 } 448 }
444 if (pmd_async_state->pending_dump_providers.empty()) 449 if (pmd_async_state->pending_dump_providers.empty())
445 return FinalizeDumpAndAddToTrace(std::move(pmd_async_state)); 450 return FinalizeDumpAndAddToTrace(std::move(pmd_async_state));
446 451
447 // Read MemoryDumpProviderInfo thread safety considerations in 452 // Read MemoryDumpProviderInfo thread safety considerations in
448 // memory_dump_manager.h when accessing |mdpinfo| fields. 453 // memory_dump_manager.h when accessing |mdpinfo| fields.
449 MemoryDumpProviderInfo* mdpinfo = 454 MemoryDumpProviderInfo* mdpinfo =
450 pmd_async_state->pending_dump_providers.back().get(); 455 pmd_async_state->pending_dump_providers.back().get();
451 456
457 // If we are in background tracing, we should invoke only the whitelisted
458 // providers. Ignore other providers and continue.
459 if (pmd_async_state->req_args.level_of_detail ==
460 MemoryDumpLevelOfDetail::BACKGROUND &&
461 !mdpinfo->whitelisted_for_background_mode) {
462 pmd_async_state->pending_dump_providers.pop_back();
463 return SetupNextMemoryDump(std::move(pmd_async_state));
464 }
465
452 // If the dump provider did not specify a task runner affinity, dump on 466 // If the dump provider did not specify a task runner affinity, dump on
453 // |dump_thread_| which is already checked above for presence. 467 // |dump_thread_| which is already checked above for presence.
454 SequencedTaskRunner* task_runner = mdpinfo->task_runner.get(); 468 SequencedTaskRunner* task_runner = mdpinfo->task_runner.get();
455 if (!task_runner) { 469 if (!task_runner) {
456 DCHECK(mdpinfo->options.dumps_on_single_thread_task_runner); 470 DCHECK(mdpinfo->options.dumps_on_single_thread_task_runner);
457 task_runner = pmd_async_state->dump_thread_task_runner.get(); 471 task_runner = pmd_async_state->dump_thread_task_runner.get();
458 DCHECK(task_runner); 472 DCHECK(task_runner);
459 } 473 }
460 474
461 if (mdpinfo->options.dumps_on_single_thread_task_runner && 475 if (mdpinfo->options.dumps_on_single_thread_task_runner &&
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 // while the |lock_| is taken; 639 // while the |lock_| is taken;
626 TraceLog::GetInstance()->InitializeThreadLocalEventBufferIfSupported(); 640 TraceLog::GetInstance()->InitializeThreadLocalEventBufferIfSupported();
627 641
628 // Spin-up the thread used to invoke unbound dump providers. 642 // Spin-up the thread used to invoke unbound dump providers.
629 std::unique_ptr<Thread> dump_thread(new Thread("MemoryInfra")); 643 std::unique_ptr<Thread> dump_thread(new Thread("MemoryInfra"));
630 if (!dump_thread->Start()) { 644 if (!dump_thread->Start()) {
631 LOG(ERROR) << "Failed to start the memory-infra thread for tracing"; 645 LOG(ERROR) << "Failed to start the memory-infra thread for tracing";
632 return; 646 return;
633 } 647 }
634 648
635 AutoLock lock(lock_); 649 const TraceConfig trace_config =
636 650 TraceLog::GetInstance()->GetCurrentTraceConfig();
637 DCHECK(delegate_); // At this point we must have a delegate. 651 scoped_refptr<MemoryDumpSessionState> session_state =
638 session_state_ = new MemoryDumpSessionState; 652 new MemoryDumpSessionState;
639 653 session_state->SetMemoryDumpConfig(trace_config.memory_dump_config());
640 if (heap_profiling_enabled_) { 654 if (heap_profiling_enabled_) {
641 // If heap profiling is enabled, the stack frame deduplicator and type name 655 // If heap profiling is enabled, the stack frame deduplicator and type name
642 // deduplicator will be in use. Add a metadata events to write the frames 656 // deduplicator will be in use. Add a metadata events to write the frames
643 // and type IDs. 657 // and type IDs.
644 session_state_->SetStackFrameDeduplicator( 658 session_state->SetStackFrameDeduplicator(
645 WrapUnique(new StackFrameDeduplicator)); 659 WrapUnique(new StackFrameDeduplicator));
646 660
647 session_state_->SetTypeNameDeduplicator( 661 session_state->SetTypeNameDeduplicator(
648 WrapUnique(new TypeNameDeduplicator)); 662 WrapUnique(new TypeNameDeduplicator));
649 663
650 TRACE_EVENT_API_ADD_METADATA_EVENT( 664 TRACE_EVENT_API_ADD_METADATA_EVENT(
651 TraceLog::GetCategoryGroupEnabled("__metadata"), "stackFrames", 665 TraceLog::GetCategoryGroupEnabled("__metadata"), "stackFrames",
652 "stackFrames", 666 "stackFrames",
653 WrapUnique( 667 WrapUnique(new SessionStateConvertableProxy<StackFrameDeduplicator>(
654 new SessionStateConvertableProxy<StackFrameDeduplicator>( 668 session_state, &MemoryDumpSessionState::stack_frame_deduplicator)));
655 session_state_,
656 &MemoryDumpSessionState::stack_frame_deduplicator)));
657 669
658 TRACE_EVENT_API_ADD_METADATA_EVENT( 670 TRACE_EVENT_API_ADD_METADATA_EVENT(
659 TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames", 671 TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames",
660 "typeNames", 672 "typeNames",
661 WrapUnique(new SessionStateConvertableProxy<TypeNameDeduplicator>( 673 WrapUnique(new SessionStateConvertableProxy<TypeNameDeduplicator>(
662 session_state_, &MemoryDumpSessionState::type_name_deduplicator))); 674 session_state, &MemoryDumpSessionState::type_name_deduplicator)));
663 } 675 }
664 676
665 DCHECK(!dump_thread_); 677 {
666 dump_thread_ = std::move(dump_thread); 678 AutoLock lock(lock_);
667 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1);
668 679
669 // TODO(primiano): This is a temporary hack to disable periodic memory dumps 680 DCHECK(delegate_); // At this point we must have a delegate.
670 // when running memory benchmarks until telemetry uses TraceConfig to 681 session_state_ = session_state;
671 // enable/disable periodic dumps. See crbug.com/529184 . 682
672 if (!is_coordinator_ || 683 DCHECK(!dump_thread_);
673 CommandLine::ForCurrentProcess()->HasSwitch( 684 dump_thread_ = std::move(dump_thread);
674 "enable-memory-benchmarking")) { 685
675 return; 686 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1);
687
688 // TODO(primiano): This is a temporary hack to disable periodic memory dumps
689 // when running memory benchmarks until telemetry uses TraceConfig to
690 // enable/disable periodic dumps. See crbug.com/529184 .
691 if (!is_coordinator_ ||
692 CommandLine::ForCurrentProcess()->HasSwitch(
693 "enable-memory-benchmarking")) {
694 return;
695 }
676 } 696 }
677 697
678 // Enable periodic dumps. At the moment the periodic support is limited to at 698 // Enable periodic dumps if necessary.
679 // most one low-detail periodic dump and at most one high-detail periodic 699 periodic_dump_timer_.Start(trace_config.memory_dump_config().triggers);
680 // dump. If both are specified the high-detail period must be an integer
681 // multiple of the low-level one.
682 g_periodic_dumps_count = 0;
683 const TraceConfig trace_config =
684 TraceLog::GetInstance()->GetCurrentTraceConfig();
685 session_state_->SetMemoryDumpConfig(trace_config.memory_dump_config());
686 const std::vector<TraceConfig::MemoryDumpConfig::Trigger>& triggers_list =
687 trace_config.memory_dump_config().triggers;
688 if (triggers_list.empty())
689 return;
690
691 uint32_t min_timer_period_ms = std::numeric_limits<uint32_t>::max();
692 uint32_t heavy_dump_period_ms = 0;
693 DCHECK_LE(triggers_list.size(), 2u);
694 for (const TraceConfig::MemoryDumpConfig::Trigger& config : triggers_list) {
695 DCHECK(config.periodic_interval_ms);
696 if (config.level_of_detail == MemoryDumpLevelOfDetail::DETAILED)
697 heavy_dump_period_ms = config.periodic_interval_ms;
698 min_timer_period_ms =
699 std::min(min_timer_period_ms, config.periodic_interval_ms);
700 }
701 DCHECK_EQ(0u, heavy_dump_period_ms % min_timer_period_ms);
702 g_heavy_dumps_rate = heavy_dump_period_ms / min_timer_period_ms;
703
704 periodic_dump_timer_.Start(FROM_HERE,
705 TimeDelta::FromMilliseconds(min_timer_period_ms),
706 base::Bind(&RequestPeriodicGlobalDump));
707 } 700 }
708 701
709 void MemoryDumpManager::OnTraceLogDisabled() { 702 void MemoryDumpManager::OnTraceLogDisabled() {
710 // There might be a memory dump in progress while this happens. Therefore, 703 // There might be a memory dump in progress while this happens. Therefore,
711 // ensure that the MDM state which depends on the tracing enabled / disabled 704 // ensure that the MDM state which depends on the tracing enabled / disabled
712 // state is always accessed by the dumping methods holding the |lock_|. 705 // state is always accessed by the dumping methods holding the |lock_|.
713 subtle::NoBarrier_Store(&memory_tracing_enabled_, 0); 706 subtle::NoBarrier_Store(&memory_tracing_enabled_, 0);
714 std::unique_ptr<Thread> dump_thread; 707 std::unique_ptr<Thread> dump_thread;
715 { 708 {
716 AutoLock lock(lock_); 709 AutoLock lock(lock_);
717 dump_thread = std::move(dump_thread_); 710 dump_thread = std::move(dump_thread_);
718 session_state_ = nullptr; 711 session_state_ = nullptr;
719 } 712 }
720 713
721 // Thread stops are blocking and must be performed outside of the |lock_| 714 // Thread stops are blocking and must be performed outside of the |lock_|
722 // or will deadlock (e.g., if SetupNextMemoryDump() tries to acquire it). 715 // or will deadlock (e.g., if SetupNextMemoryDump() tries to acquire it).
723 periodic_dump_timer_.Stop(); 716 periodic_dump_timer_.Stop();
724 if (dump_thread) 717 if (dump_thread)
725 dump_thread->Stop(); 718 dump_thread->Stop();
726 } 719 }
727 720
728 uint64_t MemoryDumpManager::GetTracingProcessId() const { 721 uint64_t MemoryDumpManager::GetTracingProcessId() const {
729 return delegate_->GetTracingProcessId(); 722 return delegate_->GetTracingProcessId();
730 } 723 }
731 724
732 MemoryDumpManager::MemoryDumpProviderInfo::MemoryDumpProviderInfo( 725 MemoryDumpManager::MemoryDumpProviderInfo::MemoryDumpProviderInfo(
733 MemoryDumpProvider* dump_provider, 726 MemoryDumpProvider* dump_provider,
734 const char* name, 727 const char* name,
735 scoped_refptr<SequencedTaskRunner> task_runner, 728 scoped_refptr<SequencedTaskRunner> task_runner,
736 const MemoryDumpProvider::Options& options) 729 const MemoryDumpProvider::Options& options,
730 bool whitelisted_for_background_mode)
737 : dump_provider(dump_provider), 731 : dump_provider(dump_provider),
738 name(name), 732 name(name),
739 task_runner(std::move(task_runner)), 733 task_runner(std::move(task_runner)),
740 options(options), 734 options(options),
741 consecutive_failures(0), 735 consecutive_failures(0),
742 disabled(false) {} 736 disabled(false),
737 whitelisted_for_background_mode(whitelisted_for_background_mode) {}
743 738
744 MemoryDumpManager::MemoryDumpProviderInfo::~MemoryDumpProviderInfo() {} 739 MemoryDumpManager::MemoryDumpProviderInfo::~MemoryDumpProviderInfo() {}
745 740
746 bool MemoryDumpManager::MemoryDumpProviderInfo::Comparator::operator()( 741 bool MemoryDumpManager::MemoryDumpProviderInfo::Comparator::operator()(
747 const scoped_refptr<MemoryDumpManager::MemoryDumpProviderInfo>& a, 742 const scoped_refptr<MemoryDumpManager::MemoryDumpProviderInfo>& a,
748 const scoped_refptr<MemoryDumpManager::MemoryDumpProviderInfo>& b) const { 743 const scoped_refptr<MemoryDumpManager::MemoryDumpProviderInfo>& b) const {
749 if (!a || !b) 744 if (!a || !b)
750 return a.get() < b.get(); 745 return a.get() < b.get();
751 // Ensure that unbound providers (task_runner == nullptr) always run last. 746 // Ensure that unbound providers (task_runner == nullptr) always run last.
752 // Rationale: some unbound dump providers are known to be slow, keep them last 747 // Rationale: some unbound dump providers are known to be slow, keep them last
(...skipping 25 matching lines...) Expand all
778 GetOrCreateMemoryDumpContainerForProcess(ProcessId pid) { 773 GetOrCreateMemoryDumpContainerForProcess(ProcessId pid) {
779 auto iter = process_dumps.find(pid); 774 auto iter = process_dumps.find(pid);
780 if (iter == process_dumps.end()) { 775 if (iter == process_dumps.end()) {
781 std::unique_ptr<ProcessMemoryDump> new_pmd( 776 std::unique_ptr<ProcessMemoryDump> new_pmd(
782 new ProcessMemoryDump(session_state)); 777 new ProcessMemoryDump(session_state));
783 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; 778 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first;
784 } 779 }
785 return iter->second.get(); 780 return iter->second.get();
786 } 781 }
787 782
783 MemoryDumpManager::PeriodicGlobalDumpTimer::PeriodicGlobalDumpTimer() {}
784
785 MemoryDumpManager::PeriodicGlobalDumpTimer::~PeriodicGlobalDumpTimer() {
786 Stop();
787 }
788
789 void MemoryDumpManager::PeriodicGlobalDumpTimer::Start(
790 const std::vector<TraceConfig::MemoryDumpConfig::Trigger>& triggers_list) {
791 if (triggers_list.empty())
792 return;
793
794 // At the moment the periodic support is limited to at most one periodic
795 // trigger per dump mode. All intervals should be an integer multiple of the
796 // smallest interval specified.
797 periodic_dumps_count_ = 0;
798 uint32_t min_timer_period_ms = std::numeric_limits<uint32_t>::max();
799 uint32_t light_dump_period_ms = 0;
800 uint32_t heavy_dump_period_ms = 0;
801 DCHECK_LE(triggers_list.size(), 3u);
802 for (const TraceConfig::MemoryDumpConfig::Trigger& config : triggers_list) {
803 DCHECK_NE(0u, config.periodic_interval_ms);
804 if (config.level_of_detail == MemoryDumpLevelOfDetail::LIGHT) {
805 DCHECK_EQ(0u, light_dump_period_ms);
806 light_dump_period_ms = config.periodic_interval_ms;
807 } else if (config.level_of_detail == MemoryDumpLevelOfDetail::DETAILED) {
808 DCHECK_EQ(0u, heavy_dump_period_ms);
809 heavy_dump_period_ms = config.periodic_interval_ms;
810 }
811 min_timer_period_ms =
812 std::min(min_timer_period_ms, config.periodic_interval_ms);
813 }
814
815 DCHECK_EQ(0u, light_dump_period_ms % min_timer_period_ms);
816 light_dump_rate_ = light_dump_period_ms / min_timer_period_ms;
817 DCHECK_EQ(0u, heavy_dump_period_ms % min_timer_period_ms);
818 heavy_dump_rate_ = heavy_dump_period_ms / min_timer_period_ms;
819
820 timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(min_timer_period_ms),
821 base::Bind(&PeriodicGlobalDumpTimer::RequestPeriodicGlobalDump,
822 base::Unretained(this)));
823 }
824
825 void MemoryDumpManager::PeriodicGlobalDumpTimer::Stop() {
826 if (IsRunning()) {
827 timer_.Stop();
828 }
829 }
830
831 bool MemoryDumpManager::PeriodicGlobalDumpTimer::IsRunning() {
832 return timer_.IsRunning();
833 }
834
835 void MemoryDumpManager::PeriodicGlobalDumpTimer::RequestPeriodicGlobalDump() {
836 MemoryDumpLevelOfDetail level_of_detail = MemoryDumpLevelOfDetail::BACKGROUND;
837 if (light_dump_rate_ > 0 && periodic_dumps_count_ % light_dump_rate_ == 0)
838 level_of_detail = MemoryDumpLevelOfDetail::LIGHT;
839 if (heavy_dump_rate_ > 0 && periodic_dumps_count_ % heavy_dump_rate_ == 0)
840 level_of_detail = MemoryDumpLevelOfDetail::DETAILED;
841 ++periodic_dumps_count_;
842
843 MemoryDumpManager::GetInstance()->RequestGlobalDump(
844 MemoryDumpType::PERIODIC_INTERVAL, level_of_detail);
845 }
846
788 } // namespace trace_event 847 } // namespace trace_event
789 } // namespace base 848 } // namespace base
OLDNEW
« no previous file with comments | « base/trace_event/memory_dump_manager.h ('k') | base/trace_event/memory_dump_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698