Chromium Code Reviews| 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 5e34147063662d016ddb8ef003eb21928801a03d..542a741a921afc65f93dba4f71e87d0b4849f2bd 100644 |
| --- a/base/trace_event/memory_dump_manager.cc |
| +++ b/base/trace_event/memory_dump_manager.cc |
| @@ -284,6 +284,16 @@ void MemoryDumpManager::RegisterDumpProviderInternal( |
| // path for RenderThreadImpl::Init(). |
| if (already_registered) |
| return; |
| + |
| + // The list of polling MDPs is populated OnTraceLogEnabled(). This code |
| + // deals with the case of a MDP capable of fast polling that is registered |
| + // after the OnTraceLogEnabled() |
| + if (options.is_fast_polling_supported && dump_thread_ && session_state_ && |
| + session_state_->is_polling_enabled()) { |
| + dump_thread_->task_runner()->PostTask( |
| + FROM_HERE, Bind(&MemoryDumpManager::RegisterPollingMDPOnDumpThread, |
| + Unretained(this), mdpinfo)); |
| + } |
| } |
| if (heap_profiling_enabled_) |
| @@ -322,6 +332,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 |dumps_providers_for_polling_|. |
| DCHECK(!(*mdp_iter)->owned_dump_provider); |
| (*mdp_iter)->owned_dump_provider = std::move(owned_mdp); |
| } else if (subtle::NoBarrier_Load(&memory_tracing_enabled_)) { |
| @@ -340,6 +351,17 @@ void MemoryDumpManager::UnregisterDumpProviderInternal( |
| << "unregister itself in a racy way. Please file a crbug."; |
| } |
| + if ((*mdp_iter)->options.is_fast_polling_supported && dump_thread_ && |
| + session_state_ && session_state_->is_polling_enabled()) { |
| + DCHECK(take_mdp_ownership_and_delete_async) |
| + << "MemoryDumpProviders capable of fast polling must NOT be thread " |
| + "bound and hence destroyed using " |
|
Primiano Tucci (use gerrit)
2016/12/16 12:34:40
+"must be" before destroyed. Otherwise is not clea
ssid
2016/12/16 18:58:22
Done.
|
| + "UnregisterAndDeleteDumpProviderSoon()"; |
| + 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() |
| @@ -349,6 +371,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_); |
| + dumps_providers_for_polling_.insert(mdpinfo); |
| +} |
| + |
| +void MemoryDumpManager::UnregisterPollingMDPOnDumpThread( |
| + scoped_refptr<MemoryDumpManager::MemoryDumpProviderInfo> mdpinfo) { |
| + mdpinfo->dump_provider->SetFastMemoryPollingEnabled(false); |
| + |
| + AutoLock lock(lock_); |
| + dumps_providers_for_polling_.erase(mdpinfo); |
| +} |
| + |
| void MemoryDumpManager::RequestGlobalDump( |
| MemoryDumpType dump_type, |
| MemoryDumpLevelOfDetail level_of_detail, |
| @@ -602,6 +641,18 @@ void MemoryDumpManager::InvokeOnMemoryDump( |
| SetupNextMemoryDump(std::move(pmd_async_state)); |
| } |
| +void MemoryDumpManager::PollFastMemoryTotal(uint64_t* memory_total) { |
| + *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 : dumps_providers_for_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) { |
| @@ -715,6 +766,16 @@ void MemoryDumpManager::OnTraceLogEnabled() { |
| DCHECK(!dump_thread_); |
| dump_thread_ = std::move(dump_thread); |
| + dumps_providers_for_polling_.clear(); |
| + if (session_state_->is_polling_enabled()) { |
| + for (const auto& mdpinfo : dump_providers_) { |
| + if (mdpinfo->options.is_fast_polling_supported) { |
| + dumps_providers_for_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 |
| @@ -735,12 +796,14 @@ void MemoryDumpManager::OnTraceLogDisabled() { |
| // There might be a memory dump in progress while this happens. Therefore, |
| // ensure that the MDM state which depends on the tracing enabled / disabled |
| // state is always accessed by the dumping methods holding the |lock_|. |
| + if (!subtle::NoBarrier_Load(&memory_tracing_enabled_)) |
|
Primiano Tucci (use gerrit)
2016/12/16 12:34:40
why is this required?
ssid
2016/12/16 18:58:22
Not really required, just an optimization to retur
Primiano Tucci (use gerrit)
2016/12/16 20:29:10
Ahh I see the point now, right . Good point.
|
| + return; |
| subtle::NoBarrier_Store(&memory_tracing_enabled_, 0); |
| + |
| std::unique_ptr<Thread> dump_thread; |
| { |
| AutoLock lock(lock_); |
| dump_thread = std::move(dump_thread_); |
| - session_state_ = nullptr; |
| } |
| // Thread stops are blocking and must be performed outside of the |lock_| |
| @@ -748,6 +811,18 @@ void MemoryDumpManager::OnTraceLogDisabled() { |
| periodic_dump_timer_.Stop(); |
| if (dump_thread) |
| dump_thread->Stop(); |
| + |
| + // |dumps_providers_for_polling_| must be cleared only after the dump thread |
| + // is stopped (polling tasks are done). |
| + { |
| + AutoLock lock(lock_); |
| + if (session_state_ && session_state_->is_polling_enabled()) { |
| + for (const auto& mdpinfo : dumps_providers_for_polling_) |
| + mdpinfo->dump_provider->SetFastMemoryPollingEnabled(false); |
| + dumps_providers_for_polling_.clear(); |
| + } |
| + session_state_ = nullptr; |
|
Primiano Tucci (use gerrit)
2016/12/16 12:34:40
let's put this back in place (see my comment on la
ssid
2016/12/16 18:58:22
Done.
|
| + } |
| } |
| bool MemoryDumpManager::IsDumpModeAllowed(MemoryDumpLevelOfDetail dump_mode) { |