Index: base/trace_event/memory_dump_manager.cc |
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc |
index 5fe9c8506790bb51ef8e7dde780dfff63a435ea4..760ed33a175f1ad252f62a268124bbc5000eb748 100644 |
--- a/base/trace_event/memory_dump_manager.cc |
+++ b/base/trace_event/memory_dump_manager.cc |
@@ -283,6 +283,12 @@ void MemoryDumpManager::RegisterDumpProviderInternal( |
// path for RenderThreadImpl::Init(). |
if (already_registered) |
return; |
+ |
+ if (options.is_fast_polling_supported && dump_thread_) { |
+ dump_thread_->task_runner()->PostTask( |
+ FROM_HERE, Bind(&MemoryDumpManager::RegisterPollingMDPOnDumpThread, |
+ Unretained(this), mdpinfo)); |
+ } |
} |
if (heap_profiling_enabled_) |
@@ -321,6 +327,7 @@ void MemoryDumpManager::UnregisterDumpProviderInternal( |
// - At the end of this function, if no dump is in progress. |
// - Either in SetupNextMemoryDump() or InvokeOnMemoryDump() when MDPInfo is |
// removed from |pending_dump_providers|. |
+ // - When the provider is removed from |mdps_for_fast_polling_|. |
DCHECK(!(*mdp_iter)->owned_dump_provider); |
(*mdp_iter)->owned_dump_provider = std::move(owned_mdp); |
} else if (subtle::NoBarrier_Load(&memory_tracing_enabled_)) { |
@@ -339,6 +346,12 @@ void MemoryDumpManager::UnregisterDumpProviderInternal( |
<< "unregister itself in a racy way. Please file a crbug."; |
} |
+ if ((*mdp_iter)->options.is_fast_polling_supported && dump_thread_) { |
+ dump_thread_->task_runner()->PostTask( |
+ FROM_HERE, Bind(&MemoryDumpManager::UnregisterPollingMDPOnDumpThread, |
+ Unretained(this), *mdp_iter)); |
+ } |
+ |
// The MDPInfo instance can still be referenced by the |
// |ProcessMemoryDumpAsyncState.pending_dump_providers|. For this reason |
// the MDPInfo is flagged as disabled. It will cause InvokeOnMemoryDump() |
@@ -348,6 +361,23 @@ void MemoryDumpManager::UnregisterDumpProviderInternal( |
dump_providers_.erase(mdp_iter); |
} |
+void MemoryDumpManager::RegisterPollingMDPOnDumpThread( |
+ scoped_refptr<MemoryDumpManager::MemoryDumpProviderInfo> mdpinfo) { |
+ DCHECK(!mdpinfo->task_runner); |
+ mdpinfo->dump_provider->SetFastMemoryPollingEnabled(true); |
+ |
+ AutoLock lock(lock_); |
+ mdps_for_fast_polling_.insert(mdpinfo); |
+} |
+ |
+void MemoryDumpManager::UnregisterPollingMDPOnDumpThread( |
+ scoped_refptr<MemoryDumpManager::MemoryDumpProviderInfo> mdpinfo) { |
+ mdpinfo->dump_provider->SetFastMemoryPollingEnabled(false); |
+ |
+ AutoLock lock(lock_); |
+ mdps_for_fast_polling_.erase(mdpinfo); |
+} |
+ |
void MemoryDumpManager::RequestGlobalDump( |
MemoryDumpType dump_type, |
MemoryDumpLevelOfDetail level_of_detail, |
@@ -601,6 +631,24 @@ void MemoryDumpManager::InvokeOnMemoryDump( |
SetupNextMemoryDump(std::move(pmd_async_state)); |
} |
+void MemoryDumpManager::PollFastMemoryTotal(uint64_t* memory_total) { |
+#if DCHECK_IS_ON() |
+ { |
+ AutoLock lock(lock_); |
+ DCHECK(dump_thread_->task_runner()->BelongsToCurrentThread()); |
+ } |
+#endif |
+ *memory_total = 0; |
+ // Note that we call PollFastMemoryTotal even if the dump provider is disabled |
+ // (unregistered). This is to avoid taking lock slowing this method. |
+ for (const auto& mdpinfo : mdps_for_fast_polling_) { |
+ uint64_t value = 0; |
+ mdpinfo->dump_provider->PollFastMemoryTotal(&value); |
+ *memory_total += value; |
+ } |
+ return; |
+} |
+ |
// static |
void MemoryDumpManager::FinalizeDumpAndAddToTrace( |
std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state) { |
@@ -714,6 +762,13 @@ void MemoryDumpManager::OnTraceLogEnabled() { |
DCHECK(!dump_thread_); |
dump_thread_ = std::move(dump_thread); |
+ mdps_for_fast_polling_.clear(); |
+ for (const auto& mdpinfo : dump_providers_) { |
+ if (mdpinfo->options.is_fast_polling_supported) |
+ mdps_for_fast_polling_.insert(mdpinfo); |
+ mdpinfo->dump_provider->SetFastMemoryPollingEnabled(true); |
+ } |
+ |
subtle::NoBarrier_Store(&memory_tracing_enabled_, 1); |
// TODO(primiano): This is a temporary hack to disable periodic memory dumps |
@@ -747,6 +802,15 @@ void MemoryDumpManager::OnTraceLogDisabled() { |
periodic_dump_timer_.Stop(); |
if (dump_thread) |
dump_thread->Stop(); |
+ |
+ // |mdps_for_fast_polling_| must be cleared only after the dump thread is |
+ // stopped (polling tasks are done). |
+ { |
+ AutoLock lock(lock_); |
+ for (const auto& mdpinfo : mdps_for_fast_polling_) |
+ mdpinfo->dump_provider->SetFastMemoryPollingEnabled(false); |
+ mdps_for_fast_polling_.clear(); |
+ } |
} |
bool MemoryDumpManager::IsDumpModeAllowed(MemoryDumpLevelOfDetail dump_mode) { |