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

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

Issue 2743993004: [memory-infra] Make MemoryDumpScheduler non-thread safe singleton (Closed)
Patch Set: rebase. Created 3 years, 9 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/allocator/features.h" 10 #include "base/allocator/features.h"
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
411 411
412 void MemoryDumpManager::RegisterPollingMDPOnDumpThread( 412 void MemoryDumpManager::RegisterPollingMDPOnDumpThread(
413 scoped_refptr<MemoryDumpManager::MemoryDumpProviderInfo> mdpinfo) { 413 scoped_refptr<MemoryDumpManager::MemoryDumpProviderInfo> mdpinfo) {
414 AutoLock lock(lock_); 414 AutoLock lock(lock_);
415 dump_providers_for_polling_.insert(mdpinfo); 415 dump_providers_for_polling_.insert(mdpinfo);
416 416
417 // Notify ready for polling when first polling supported provider is 417 // Notify ready for polling when first polling supported provider is
418 // registered. This handles the case where OnTraceLogEnabled() did not notify 418 // registered. This handles the case where OnTraceLogEnabled() did not notify
419 // ready since no polling supported mdp has yet been registered. 419 // ready since no polling supported mdp has yet been registered.
420 if (dump_providers_for_polling_.size() == 1) 420 if (dump_providers_for_polling_.size() == 1)
421 dump_scheduler_->NotifyPollingSupported(); 421 MemoryDumpScheduler::GetInstance()->EnablePollingIfNeeded();
422 } 422 }
423 423
424 void MemoryDumpManager::UnregisterPollingMDPOnDumpThread( 424 void MemoryDumpManager::UnregisterPollingMDPOnDumpThread(
425 scoped_refptr<MemoryDumpManager::MemoryDumpProviderInfo> mdpinfo) { 425 scoped_refptr<MemoryDumpManager::MemoryDumpProviderInfo> mdpinfo) {
426 mdpinfo->dump_provider->SuspendFastMemoryPolling(); 426 mdpinfo->dump_provider->SuspendFastMemoryPolling();
427 427
428 AutoLock lock(lock_); 428 AutoLock lock(lock_);
429 dump_providers_for_polling_.erase(mdpinfo); 429 dump_providers_for_polling_.erase(mdpinfo);
430 DCHECK(!dump_providers_for_polling_.empty()) 430 DCHECK(!dump_providers_for_polling_.empty())
431 << "All polling MDPs cannot be unregistered."; 431 << "All polling MDPs cannot be unregistered.";
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 pmd_async_state.reset(new ProcessMemoryDumpAsyncState( 505 pmd_async_state.reset(new ProcessMemoryDumpAsyncState(
506 args, dump_providers_, session_state_, callback, 506 args, dump_providers_, session_state_, callback,
507 dump_thread_ ? dump_thread_->task_runner() : nullptr)); 507 dump_thread_ ? dump_thread_->task_runner() : nullptr));
508 508
509 // Safety check to prevent reaching here without calling RequestGlobalDump, 509 // Safety check to prevent reaching here without calling RequestGlobalDump,
510 // with disallowed modes. If |session_state_| is null then tracing is 510 // with disallowed modes. If |session_state_| is null then tracing is
511 // disabled. 511 // disabled.
512 CHECK(!session_state_ || 512 CHECK(!session_state_ ||
513 session_state_->IsDumpModeAllowed(args.level_of_detail)); 513 session_state_->IsDumpModeAllowed(args.level_of_detail));
514 514
515 if (dump_scheduler_) 515 MemoryDumpScheduler::GetInstance()->NotifyDumpTriggered();
516 dump_scheduler_->NotifyDumpTriggered();
517 } 516 }
518 517
519 TRACE_EVENT_WITH_FLOW0(kTraceCategory, "MemoryDumpManager::CreateProcessDump", 518 TRACE_EVENT_WITH_FLOW0(kTraceCategory, "MemoryDumpManager::CreateProcessDump",
520 TRACE_ID_MANGLE(args.dump_guid), 519 TRACE_ID_MANGLE(args.dump_guid),
521 TRACE_EVENT_FLAG_FLOW_OUT); 520 TRACE_EVENT_FLAG_FLOW_OUT);
522 521
523 // Start the process dump. This involves task runner hops as specified by the 522 // Start the process dump. This involves task runner hops as specified by the
524 // MemoryDumpProvider(s) in RegisterDumpProvider()). 523 // MemoryDumpProvider(s) in RegisterDumpProvider()).
525 SetupNextMemoryDump(std::move(pmd_async_state)); 524 SetupNextMemoryDump(std::move(pmd_async_state));
526 } 525 }
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 MakeUnique<SessionStateConvertableProxy<StackFrameDeduplicator>>( 818 MakeUnique<SessionStateConvertableProxy<StackFrameDeduplicator>>(
820 session_state, &MemoryDumpSessionState::stack_frame_deduplicator)); 819 session_state, &MemoryDumpSessionState::stack_frame_deduplicator));
821 820
822 TRACE_EVENT_API_ADD_METADATA_EVENT( 821 TRACE_EVENT_API_ADD_METADATA_EVENT(
823 TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames", 822 TraceLog::GetCategoryGroupEnabled("__metadata"), "typeNames",
824 "typeNames", 823 "typeNames",
825 MakeUnique<SessionStateConvertableProxy<TypeNameDeduplicator>>( 824 MakeUnique<SessionStateConvertableProxy<TypeNameDeduplicator>>(
826 session_state, &MemoryDumpSessionState::type_name_deduplicator)); 825 session_state, &MemoryDumpSessionState::type_name_deduplicator));
827 } 826 }
828 827
829 std::unique_ptr<MemoryDumpScheduler> dump_scheduler(
830 new MemoryDumpScheduler(this, dump_thread->task_runner()));
831 DCHECK_LE(memory_dump_config.triggers.size(), 3u);
832 for (const auto& trigger : memory_dump_config.triggers) {
833 if (!session_state->IsDumpModeAllowed(trigger.level_of_detail)) {
834 NOTREACHED();
835 continue;
836 }
837 dump_scheduler->AddTrigger(trigger.trigger_type, trigger.level_of_detail,
838 trigger.min_time_between_dumps_ms);
839 }
840
841 { 828 {
842 AutoLock lock(lock_); 829 AutoLock lock(lock_);
843 830
844 DCHECK(delegate_); // At this point we must have a delegate. 831 DCHECK(delegate_); // At this point we must have a delegate.
845 session_state_ = session_state; 832 session_state_ = session_state;
846 833
847 DCHECK(!dump_thread_); 834 DCHECK(!dump_thread_);
848 dump_thread_ = std::move(dump_thread); 835 dump_thread_ = std::move(dump_thread);
849 dump_scheduler_ = std::move(dump_scheduler);
850 836
851 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1); 837 subtle::NoBarrier_Store(&memory_tracing_enabled_, 1);
852 838
853 dump_providers_for_polling_.clear(); 839 dump_providers_for_polling_.clear();
854 for (const auto& mdpinfo : dump_providers_) { 840 for (const auto& mdpinfo : dump_providers_) {
855 if (mdpinfo->options.is_fast_polling_supported) 841 if (mdpinfo->options.is_fast_polling_supported)
856 dump_providers_for_polling_.insert(mdpinfo); 842 dump_providers_for_polling_.insert(mdpinfo);
857 } 843 }
844
845 MemoryDumpScheduler* dump_scheduler = MemoryDumpScheduler::GetInstance();
846 dump_scheduler->Setup(this, dump_thread_->task_runner());
847 DCHECK_LE(memory_dump_config.triggers.size(), 3u);
848 for (const auto& trigger : memory_dump_config.triggers) {
849 if (!session_state_->IsDumpModeAllowed(trigger.level_of_detail)) {
850 NOTREACHED();
851 continue;
852 }
853 dump_scheduler->AddTrigger(trigger.trigger_type, trigger.level_of_detail,
854 trigger.min_time_between_dumps_ms);
855 }
856
858 // Notify polling supported only if some polling supported provider was 857 // Notify polling supported only if some polling supported provider was
859 // registered, else RegisterPollingMDPOnDumpThread() will notify when first 858 // registered, else RegisterPollingMDPOnDumpThread() will notify when first
860 // polling MDP registers. 859 // polling MDP registers.
861 if (!dump_providers_for_polling_.empty()) 860 if (!dump_providers_for_polling_.empty())
862 dump_scheduler_->NotifyPollingSupported(); 861 dump_scheduler->EnablePollingIfNeeded();
863 862
864 // Only coordinator process triggers periodic global memory dumps. 863 // Only coordinator process triggers periodic global memory dumps.
865 if (delegate_->IsCoordinator()) 864 if (delegate_->IsCoordinator())
866 dump_scheduler_->NotifyPeriodicTriggerSupported(); 865 dump_scheduler->EnablePeriodicTriggerIfNeeded();
867 } 866 }
868 867
869 } 868 }
870 869
871 void MemoryDumpManager::OnTraceLogDisabled() { 870 void MemoryDumpManager::OnTraceLogDisabled() {
872 // There might be a memory dump in progress while this happens. Therefore, 871 // There might be a memory dump in progress while this happens. Therefore,
873 // ensure that the MDM state which depends on the tracing enabled / disabled 872 // ensure that the MDM state which depends on the tracing enabled / disabled
874 // state is always accessed by the dumping methods holding the |lock_|. 873 // state is always accessed by the dumping methods holding the |lock_|.
875 if (!subtle::NoBarrier_Load(&memory_tracing_enabled_)) 874 if (!subtle::NoBarrier_Load(&memory_tracing_enabled_))
876 return; 875 return;
877 subtle::NoBarrier_Store(&memory_tracing_enabled_, 0); 876 subtle::NoBarrier_Store(&memory_tracing_enabled_, 0);
878 std::unique_ptr<Thread> dump_thread; 877 std::unique_ptr<Thread> dump_thread;
879 std::unique_ptr<MemoryDumpScheduler> scheduler;
880 { 878 {
881 AutoLock lock(lock_); 879 AutoLock lock(lock_);
882 dump_thread = std::move(dump_thread_); 880 dump_thread = std::move(dump_thread_);
883 session_state_ = nullptr; 881 session_state_ = nullptr;
884 scheduler = std::move(dump_scheduler_); 882 MemoryDumpScheduler::GetInstance()->DisableAllTriggers();
885 } 883 }
886 scheduler->DisableAllTriggers();
887 884
888 // Thread stops are blocking and must be performed outside of the |lock_| 885 // Thread stops are blocking and must be performed outside of the |lock_|
889 // or will deadlock (e.g., if SetupNextMemoryDump() tries to acquire it). 886 // or will deadlock (e.g., if SetupNextMemoryDump() tries to acquire it).
890 if (dump_thread) 887 if (dump_thread)
891 dump_thread->Stop(); 888 dump_thread->Stop();
892 889
893 // |dump_providers_for_polling_| must be cleared only after the dump thread is 890 // |dump_providers_for_polling_| must be cleared only after the dump thread is
894 // stopped (polling tasks are done). 891 // stopped (polling tasks are done).
895 { 892 {
896 AutoLock lock(lock_); 893 AutoLock lock(lock_);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 if (iter == process_dumps.end()) { 958 if (iter == process_dumps.end()) {
962 std::unique_ptr<ProcessMemoryDump> new_pmd( 959 std::unique_ptr<ProcessMemoryDump> new_pmd(
963 new ProcessMemoryDump(session_state, dump_args)); 960 new ProcessMemoryDump(session_state, dump_args));
964 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first; 961 iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first;
965 } 962 }
966 return iter->second.get(); 963 return iter->second.get();
967 } 964 }
968 965
969 } // namespace trace_event 966 } // namespace trace_event
970 } // namespace base 967 } // 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