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

Unified Diff: base/trace_event/memory_dump_manager.cc

Issue 1427963002: [tracing] Move memory-infra dumps to dedicated thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@memory-infra-names
Patch Set: Created 5 years, 2 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 side-by-side diff with in-line comments
Download patch
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 d939eea3cef93ec13f76f2cbd59b31f90a7c8231..133ee13efd777e7b7eb01c69283dd963b1d39646 100644
--- a/base/trace_event/memory_dump_manager.cc
+++ b/base/trace_event/memory_dump_manager.cc
@@ -11,6 +11,7 @@
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/thread_task_runner_handle.h"
+#include "base/threading/thread.h"
#include "base/trace_event/memory_dump_provider.h"
#include "base/trace_event/memory_dump_session_state.h"
#include "base/trace_event/memory_profiler_allocation_context.h"
@@ -282,7 +283,8 @@ void MemoryDumpManager::CreateProcessDump(const MemoryDumpRequestArgs& args,
{
AutoLock lock(lock_);
pmd_async_state.reset(new ProcessMemoryDumpAsyncState(
- args, dump_providers_.begin(), session_state_, callback));
+ args, dump_providers_.begin(), session_state_, callback,
+ dump_thread_->task_runner()));
}
TRACE_EVENT_WITH_FLOW0(kTraceCategory, "MemoryDumpManager::CreateProcessDump",
@@ -331,10 +333,21 @@ void MemoryDumpManager::ContinueAsyncProcessDump(
auto mdp_info = pmd_async_state->next_dump_provider;
mdp = mdp_info->dump_provider;
dump_provider_name = mdp_info->name;
+
+ // If the dump provider did not specify a thread affinity, dump on the
petrcermak 2015/10/30 17:43:04 nit: "dump_thread_" is a name so I'd drop the arti
Primiano Tucci (use gerrit) 2015/11/02 10:22:22 Done.
+ // |dump_thread_|.
+ SingleThreadTaskRunner* task_runner = mdp_info->task_runner.get();
+ if (!task_runner)
+ task_runner = pmd_async_state->dump_thread_task_runner.get();
+
+ // The |dump_thread_| might have been Stop()-ed at this point (if tracing
petrcermak 2015/10/30 17:43:04 ditto
Primiano Tucci (use gerrit) 2015/11/02 10:22:22 Done.
+ // was disabled in the meanwhile). In such case the PostTask() below will
+ // fail. The task_runner handle, however, should always be non-null.
+ DCHECK(task_runner);
+
if (mdp_info->disabled || mdp_info->unregistered) {
skip_dump = true;
- } else if (mdp_info->task_runner &&
- !mdp_info->task_runner->BelongsToCurrentThread()) {
+ } else if (!task_runner->BelongsToCurrentThread()) {
// It's time to hop onto another thread.
// Copy the callback + arguments just for the unlikley case in which
@@ -343,9 +356,9 @@ void MemoryDumpManager::ContinueAsyncProcessDump(
// abort.
MemoryDumpCallback callback = pmd_async_state->callback;
scoped_refptr<SingleThreadTaskRunner> callback_task_runner =
- pmd_async_state->task_runner;
+ pmd_async_state->callback_task_runner;
- const bool did_post_task = mdp_info->task_runner->PostTask(
+ const bool did_post_task = task_runner->PostTask(
FROM_HERE, Bind(&MemoryDumpManager::ContinueAsyncProcessDump,
Unretained(this), Passed(pmd_async_state.Pass())));
if (did_post_task)
@@ -407,12 +420,12 @@ void MemoryDumpManager::ContinueAsyncProcessDump(
void MemoryDumpManager::FinalizeDumpAndAddToTrace(
scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state) {
const uint64_t dump_guid = pmd_async_state->req_args.dump_guid;
- if (!pmd_async_state->task_runner->BelongsToCurrentThread()) {
- scoped_refptr<SingleThreadTaskRunner> task_runner =
- pmd_async_state->task_runner;
- task_runner->PostTask(FROM_HERE,
- Bind(&MemoryDumpManager::FinalizeDumpAndAddToTrace,
- Passed(pmd_async_state.Pass())));
+ if (!pmd_async_state->callback_task_runner->BelongsToCurrentThread()) {
+ scoped_refptr<SingleThreadTaskRunner> callback_task_runner =
+ pmd_async_state->callback_task_runner;
+ callback_task_runner->PostTask(
+ FROM_HERE, Bind(&MemoryDumpManager::FinalizeDumpAndAddToTrace,
+ Passed(pmd_async_state.Pass())));
return;
}
@@ -483,6 +496,9 @@ void MemoryDumpManager::OnTraceLogEnabled() {
stack_frame_deduplicator);
}
+ dump_thread_.reset(new Thread("MemoryInfra"));
+ dump_thread_->Start();
Ruud van Asseldonk 2015/10/30 16:52:41 Is |new Thread| or |dump_thread_->Start()| an expe
petrcermak 2015/10/30 17:43:04 It seems like that could create a race with OnTrac
Primiano Tucci (use gerrit) 2015/11/02 10:22:23 Makes sense, moved to a temporary ref_ptr before a
+
session_state_ = new MemoryDumpSessionState(stack_frame_deduplicator);
for (auto it = dump_providers_.begin(); it != dump_providers_.end(); ++it) {
@@ -532,9 +548,16 @@ void MemoryDumpManager::OnTraceLogEnabled() {
}
void MemoryDumpManager::OnTraceLogDisabled() {
- AutoLock lock(lock_);
- periodic_dump_timer_.Stop();
subtle::NoBarrier_Store(&memory_tracing_enabled_, 0);
+
+ // Thread stops are blocking and must be performed outside of the |lock_|
+ // or will deadlock (e.g., if ContinueAsyncProcessDump() tries to acquire it).
+ periodic_dump_timer_.Stop();
+ if (dump_thread_)
Ruud van Asseldonk 2015/10/30 16:52:41 So |dump_thread_| is set inside the lock everywher
petrcermak 2015/10/30 17:43:04 I agree that would be better. It's strange (and po
Primiano Tucci (use gerrit) 2015/11/02 10:22:23 So, tecnically is fine as it is accessed only in O
+ dump_thread_->Stop();
+
+ AutoLock lock(lock_);
+ dump_thread_.reset();
session_state_ = nullptr;
}
@@ -559,19 +582,22 @@ bool MemoryDumpManager::MemoryDumpProviderInfo::operator<(
const MemoryDumpProviderInfo& other) const {
if (task_runner == other.task_runner)
return dump_provider < other.dump_provider;
- return task_runner < other.task_runner;
+ // Ensure that unbound providers (task_runner == nullptr) run always last.
petrcermak 2015/10/30 17:43:04 supernit: "always run" sounds better than "run alw
Primiano Tucci (use gerrit) 2015/11/02 10:22:23 Done.
+ return !(task_runner < other.task_runner);
Ruud van Asseldonk 2015/10/30 16:52:41 You replaced < with >= here but we already know th
Primiano Tucci (use gerrit) 2015/11/02 10:22:23 The reason why I did that is that operator< is alr
Ruud van Asseldonk 2015/11/02 11:00:37 I see. You could call |.get()| to work around.
}
MemoryDumpManager::ProcessMemoryDumpAsyncState::ProcessMemoryDumpAsyncState(
MemoryDumpRequestArgs req_args,
MemoryDumpProviderInfoSet::iterator next_dump_provider,
const scoped_refptr<MemoryDumpSessionState>& session_state,
- MemoryDumpCallback callback)
+ MemoryDumpCallback callback,
+ const scoped_refptr<SingleThreadTaskRunner>& dump_thread_task_runner)
: process_memory_dump(session_state),
req_args(req_args),
next_dump_provider(next_dump_provider),
callback(callback),
- task_runner(MessageLoop::current()->task_runner()) {}
+ callback_task_runner(MessageLoop::current()->task_runner()),
+ dump_thread_task_runner(dump_thread_task_runner) {}
MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() {
}

Powered by Google App Engine
This is Rietveld 408576698