// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/trace_event/memory_dump_manager.h"

#include <algorithm>
#include <utility>

#include "base/atomic_sequence_num.h"
#include "base/base_switches.h"
#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/heap_profiler_allocation_context_tracker.h"
#include "base/trace_event/heap_profiler_stack_frame_deduplicator.h"
#include "base/trace_event/heap_profiler_type_name_deduplicator.h"
#include "base/trace_event/malloc_dump_provider.h"
#include "base/trace_event/memory_dump_provider.h"
#include "base/trace_event/memory_dump_session_state.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event_argument.h"
#include "build/build_config.h"

#if !defined(OS_NACL)
#include "base/trace_event/process_memory_totals_dump_provider.h"
#endif

#if defined(OS_LINUX) || defined(OS_ANDROID)
#include "base/trace_event/process_memory_maps_dump_provider.h"
#endif

#if defined(OS_ANDROID)
#include "base/trace_event/java_heap_dump_provider_android.h"
#endif

#if defined(OS_WIN)
#include "base/trace_event/winheap_dump_provider_win.h"
#endif

namespace base {
namespace trace_event {

namespace {

const int kTraceEventNumArgs = 1;
const char* kTraceEventArgNames[] = {"dumps"};
const unsigned char kTraceEventArgTypes[] = {TRACE_VALUE_TYPE_CONVERTABLE};

StaticAtomicSequenceNumber g_next_guid;
uint32_t g_periodic_dumps_count = 0;
uint32_t g_heavy_dumps_rate = 0;
MemoryDumpManager* g_instance_for_testing = nullptr;

void RequestPeriodicGlobalDump() {
  MemoryDumpLevelOfDetail level_of_detail;
  if (g_heavy_dumps_rate == 0) {
    level_of_detail = MemoryDumpLevelOfDetail::LIGHT;
  } else {
    level_of_detail = g_periodic_dumps_count == 0
                          ? MemoryDumpLevelOfDetail::DETAILED
                          : MemoryDumpLevelOfDetail::LIGHT;

    if (++g_periodic_dumps_count == g_heavy_dumps_rate)
      g_periodic_dumps_count = 0;
  }

  MemoryDumpManager::GetInstance()->RequestGlobalDump(
      MemoryDumpType::PERIODIC_INTERVAL, level_of_detail);
}

// Callback wrapper to hook upon the completion of RequestGlobalDump() and
// inject trace markers.
void OnGlobalDumpDone(MemoryDumpCallback wrapped_callback,
                      uint64_t dump_guid,
                      bool success) {
  TRACE_EVENT_NESTABLE_ASYNC_END1(
      MemoryDumpManager::kTraceCategory, "GlobalMemoryDump",
      TRACE_ID_MANGLE(dump_guid), "success", success);

  if (!wrapped_callback.is_null()) {
    wrapped_callback.Run(dump_guid, success);
    wrapped_callback.Reset();
  }
}

}  // namespace

// static
const char* const MemoryDumpManager::kTraceCategory =
    TRACE_DISABLED_BY_DEFAULT("memory-infra");

// static
const int MemoryDumpManager::kMaxConsecutiveFailuresCount = 3;

// static
const uint64_t MemoryDumpManager::kInvalidTracingProcessId = 0;

// static
const char* const MemoryDumpManager::kSystemAllocatorPoolName =
#if defined(MALLOC_MEMORY_TRACING_SUPPORTED)
    MallocDumpProvider::kAllocatedObjects;
#elif defined(OS_WIN)
    WinHeapDumpProvider::kAllocatedObjects;
#else
    nullptr;
#endif

// static
MemoryDumpManager* MemoryDumpManager::GetInstance() {
  if (g_instance_for_testing)
    return g_instance_for_testing;

  return Singleton<MemoryDumpManager,
                   LeakySingletonTraits<MemoryDumpManager>>::get();
}

// static
void MemoryDumpManager::SetInstanceForTesting(MemoryDumpManager* instance) {
  g_instance_for_testing = instance;
}

MemoryDumpManager::MemoryDumpManager()
    : delegate_(nullptr),
      is_coordinator_(false),
      memory_tracing_enabled_(0),
      tracing_process_id_(kInvalidTracingProcessId),
      dumper_registrations_ignored_for_testing_(false) {
  g_next_guid.GetNext();  // Make sure that first guid is not zero.

  heap_profiling_enabled_ = CommandLine::InitializedForCurrentProcess()
                                ? CommandLine::ForCurrentProcess()->HasSwitch(
                                      switches::kEnableHeapProfiling)
                                : false;

  if (heap_profiling_enabled_)
    AllocationContextTracker::SetCaptureEnabled(true);
}

MemoryDumpManager::~MemoryDumpManager() {
  TraceLog::GetInstance()->RemoveEnabledStateObserver(this);
}

void MemoryDumpManager::Initialize(MemoryDumpManagerDelegate* delegate,
                                   bool is_coordinator) {
  {
    AutoLock lock(lock_);
    DCHECK(delegate);
    DCHECK(!delegate_);
    delegate_ = delegate;
    is_coordinator_ = is_coordinator;
  }

// Enable the core dump providers.
#if !defined(OS_NACL)
  RegisterDumpProvider(ProcessMemoryTotalsDumpProvider::GetInstance(),
                       "ProcessMemoryTotals", nullptr);
#endif

#if defined(MALLOC_MEMORY_TRACING_SUPPORTED)
  RegisterDumpProvider(MallocDumpProvider::GetInstance(), "Malloc", nullptr);
#endif

#if defined(OS_LINUX) || defined(OS_ANDROID)
  RegisterDumpProvider(ProcessMemoryMapsDumpProvider::GetInstance(),
                       "ProcessMemoryMaps", nullptr);
#endif

#if defined(OS_ANDROID)
  RegisterDumpProvider(JavaHeapDumpProvider::GetInstance(), "JavaHeap",
                       nullptr);
#endif

#if defined(OS_WIN)
  RegisterDumpProvider(WinHeapDumpProvider::GetInstance(), "WinHeap", nullptr);
#endif

  // If tracing was enabled before initializing MemoryDumpManager, we missed the
  // OnTraceLogEnabled() event. Synthetize it so we can late-join the party.
  bool is_tracing_already_enabled = TraceLog::GetInstance()->IsEnabled();
  TRACE_EVENT0(kTraceCategory, "init");  // Add to trace-viewer category list.
  TraceLog::GetInstance()->AddEnabledStateObserver(this);
  if (is_tracing_already_enabled)
    OnTraceLogEnabled();
}

void MemoryDumpManager::RegisterDumpProvider(
    MemoryDumpProvider* mdp,
    const char* name,
    const scoped_refptr<SingleThreadTaskRunner>& task_runner,
    const MemoryDumpProvider::Options& options) {
  if (dumper_registrations_ignored_for_testing_)
    return;

  MemoryDumpProviderInfo mdp_info(mdp, name, task_runner, options);
  AutoLock lock(lock_);
  auto iter_new = dump_providers_.insert(mdp_info);

  // If there was a previous entry, replace it with the new one. This is to deal
  // with the case where a dump provider unregisters itself and then re-
  // registers before a memory dump happens, so its entry was still in the
  // collection but flagged |unregistered|.
  if (!iter_new.second) {
    dump_providers_.erase(iter_new.first);
    dump_providers_.insert(mdp_info);
  }

  if (heap_profiling_enabled_)
    mdp->OnHeapProfilingEnabled(true);
}

void MemoryDumpManager::RegisterDumpProvider(
    MemoryDumpProvider* mdp,
    const char* name,
    const scoped_refptr<SingleThreadTaskRunner>& task_runner) {
  RegisterDumpProvider(mdp, name, task_runner, MemoryDumpProvider::Options());
}

void MemoryDumpManager::UnregisterDumpProvider(MemoryDumpProvider* mdp) {
  AutoLock lock(lock_);

  auto mdp_iter = dump_providers_.begin();
  for (; mdp_iter != dump_providers_.end(); ++mdp_iter) {
    if (mdp_iter->dump_provider == mdp)
      break;
  }

  if (mdp_iter == dump_providers_.end())
    return;

  // Unregistration of a MemoryDumpProvider while tracing is ongoing is safe
  // only if the MDP has specified a thread affinity (via task_runner()) AND
  // the unregistration happens on the same thread (so the MDP cannot unregister
  // and OnMemoryDump() at the same time).
  // Otherwise, it is not possible to guarantee that its unregistration is
  // race-free. If you hit this DCHECK, your MDP has a bug.
  DCHECK(!subtle::NoBarrier_Load(&memory_tracing_enabled_) ||
         (mdp_iter->task_runner &&
          mdp_iter->task_runner->BelongsToCurrentThread()))
      << "MemoryDumpProvider \"" << mdp_iter->name << "\" attempted to "
      << "unregister itself in a racy way. Please file a crbug.";

  mdp_iter->unregistered = true;
}

void MemoryDumpManager::RequestGlobalDump(
    MemoryDumpType dump_type,
    MemoryDumpLevelOfDetail level_of_detail,
    const MemoryDumpCallback& callback) {
  // Bail out immediately if tracing is not enabled at all.
  if (!UNLIKELY(subtle::NoBarrier_Load(&memory_tracing_enabled_))) {
    if (!callback.is_null())
      callback.Run(0u /* guid */, false /* success */);
    return;
  }

  const uint64_t guid =
      TraceLog::GetInstance()->MangleEventId(g_next_guid.GetNext());

  // Creates an async event to keep track of the global dump evolution.
  // The |wrapped_callback| will generate the ASYNC_END event and then invoke
  // the real |callback| provided by the caller.
  TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(kTraceCategory, "GlobalMemoryDump",
                                    TRACE_ID_MANGLE(guid));
  MemoryDumpCallback wrapped_callback = Bind(&OnGlobalDumpDone, callback);

  // Technically there is no need to grab the |lock_| here as the delegate is
  // long-lived and can only be set by Initialize(), which is locked and
  // necessarily happens before memory_tracing_enabled_ == true.
  // Not taking the |lock_|, though, is lakely make TSan barf and, at this point
  // (memory-infra is enabled) we're not in the fast-path anymore.
  MemoryDumpManagerDelegate* delegate;
  {
    AutoLock lock(lock_);
    delegate = delegate_;
  }

  // The delegate will coordinate the IPC broadcast and at some point invoke
  // CreateProcessDump() to get a dump for the current process.
  MemoryDumpRequestArgs args = {guid, dump_type, level_of_detail};
  delegate->RequestGlobalMemoryDump(args, wrapped_callback);
}

void MemoryDumpManager::RequestGlobalDump(
    MemoryDumpType dump_type,
    MemoryDumpLevelOfDetail level_of_detail) {
  RequestGlobalDump(dump_type, level_of_detail, MemoryDumpCallback());
}

void MemoryDumpManager::CreateProcessDump(const MemoryDumpRequestArgs& args,
                                          const MemoryDumpCallback& callback) {
  TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(kTraceCategory, "ProcessMemoryDump",
                                    TRACE_ID_MANGLE(args.dump_guid));

  scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state;
  {
    AutoLock lock(lock_);
    pmd_async_state.reset(new ProcessMemoryDumpAsyncState(
        args, dump_providers_.begin(), session_state_, callback,
        dump_thread_->task_runner()));
  }

  TRACE_EVENT_WITH_FLOW0(kTraceCategory, "MemoryDumpManager::CreateProcessDump",
                         TRACE_ID_MANGLE(args.dump_guid),
                         TRACE_EVENT_FLAG_FLOW_OUT);

  // Start the thread hop. |dump_providers_| are kept sorted by thread, so
  // ContinueAsyncProcessDump will hop at most once per thread (w.r.t. thread
  // affinity specified by the MemoryDumpProvider(s) in RegisterDumpProvider()).
  ContinueAsyncProcessDump(std::move(pmd_async_state));
}

// At most one ContinueAsyncProcessDump() can be active at any time for a given
// PMD, regardless of status of the |lock_|. |lock_| is used here purely to
// ensure consistency w.r.t. (un)registrations of |dump_providers_|.
// The linearization of dump providers' OnMemoryDump invocations is achieved by
// means of subsequent PostTask(s).
//
// 1) Prologue:
//   - Check if the dump provider is disabled, if so skip the dump.
//   - Check if we are on the right thread. If not hop and continue there.
// 2) Invoke the dump provider's OnMemoryDump() (unless skipped).
// 3) Epilogue:
//  - Unregister the dump provider if it failed too many times consecutively.
//  - Advance the |next_dump_provider| iterator to the next dump provider.
//  - If this was the last hop, create a trace event, add it to the trace
//    and finalize (invoke callback).

void MemoryDumpManager::ContinueAsyncProcessDump(
    scoped_ptr<ProcessMemoryDumpAsyncState> pmd_async_state) {
  // Initalizes the ThreadLocalEventBuffer to guarantee that the TRACE_EVENTs
  // in the PostTask below don't end up registering their own dump providers
  // (for discounting trace memory overhead) while holding the |lock_|.
  TraceLog::GetInstance()->InitializeThreadLocalEventBufferIfSupported();

  const uint64_t dump_guid = pmd_async_state->req_args.dump_guid;
  const char* dump_provider_name = nullptr;

  // Pid of the target process being dumped. Often kNullProcessId (= current
  // process), non-zero when the coordinator process creates dumps on behalf
  // of child processes (see crbug.com/461788).
  ProcessId pid;

  // DO NOT put any LOG() statement in the locked sections, as in some contexts
  // (GPU process) LOG() ends up performing PostTask/IPCs.
  MemoryDumpProvider* mdp;
  bool skip_dump = false;
  {
    AutoLock lock(lock_);

    auto mdp_info = pmd_async_state->next_dump_provider;
    mdp = mdp_info->dump_provider;
    dump_provider_name = mdp_info->name;
    pid = mdp_info->options.target_pid;

    // If the dump provider did not specify a thread affinity, dump on
    // |dump_thread_|.
    SingleThreadTaskRunner* task_runner = mdp_info->task_runner.get();
    if (!task_runner)
      task_runner = pmd_async_state->dump_thread_task_runner.get();

    // |dump_thread_| might have been Stop()-ed at this point (if tracing was
    // disabled in the meanwhile). In such case the PostTask() below will fail.
    // |task_runner|, however, should always be non-null.
    DCHECK(task_runner);

    if (mdp_info->disabled || mdp_info->unregistered) {
      skip_dump = true;
    } else if (!task_runner->BelongsToCurrentThread()) {
      // It's time to hop onto another thread.

      // Copy the callback + arguments just for the unlikley case in which
      // PostTask fails. In such case the Bind helper will destroy the
      // pmd_async_state and we must keep a copy of the fields to notify the
      // abort.
      MemoryDumpCallback callback = pmd_async_state->callback;
      scoped_refptr<SingleThreadTaskRunner> callback_task_runner =
          pmd_async_state->callback_task_runner;

      const bool did_post_task = task_runner->PostTask(
          FROM_HERE, Bind(&MemoryDumpManager::ContinueAsyncProcessDump,
                          Unretained(this), Passed(&pmd_async_state)));
      if (did_post_task)
        return;

      // The thread is gone. At this point the best thing we can do is to
      // disable the dump provider and abort this dump.
      mdp_info->disabled = true;
      return AbortDumpLocked(callback, callback_task_runner, dump_guid);
    }
  }  // AutoLock(lock_)

  // Invoke the dump provider without holding the |lock_|.
  bool finalize = false;
  bool dump_successful = false;

  if (!skip_dump) {
    TRACE_EVENT_WITH_FLOW1(kTraceCategory,
                           "MemoryDumpManager::ContinueAsyncProcessDump",
                           TRACE_ID_MANGLE(dump_guid),
                           TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
                           "dump_provider.name", dump_provider_name);
    MemoryDumpArgs args = {pmd_async_state->req_args.level_of_detail};
    ProcessMemoryDump* process_memory_dump =
        pmd_async_state->GetOrCreateMemoryDumpContainerForProcess(pid);
    dump_successful = mdp->OnMemoryDump(args, process_memory_dump);
  }

  {
    AutoLock lock(lock_);
    auto mdp_info = pmd_async_state->next_dump_provider;
    if (dump_successful) {
      mdp_info->consecutive_failures = 0;
    } else if (!skip_dump) {
      ++mdp_info->consecutive_failures;
      if (mdp_info->consecutive_failures >= kMaxConsecutiveFailuresCount) {
        mdp_info->disabled = true;
      }
    }
    ++pmd_async_state->next_dump_provider;
    finalize = pmd_async_state->next_dump_provider == dump_providers_.end();

    if (mdp_info->unregistered)
      dump_providers_.erase(mdp_info);
  }

  if (!skip_dump && !dump_successful) {
    LOG(ERROR) << "MemoryDumpProvider \"" << dump_provider_name << "\" failed, "
               << "possibly due to sandboxing (crbug.com/461788)."
               << "Disabling dumper for current process. Try --no-sandbox.";
  }

  if (finalize)
    return FinalizeDumpAndAddToTrace(std::move(pmd_async_state));

  ContinueAsyncProcessDump(std::move(pmd_async_state));
}

// static
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->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)));
    return;
  }

  TRACE_EVENT_WITH_FLOW0(kTraceCategory,
                         "MemoryDumpManager::FinalizeDumpAndAddToTrace",
                         TRACE_ID_MANGLE(dump_guid), TRACE_EVENT_FLAG_FLOW_IN);

  for (const auto& kv : pmd_async_state->process_dumps) {
    ProcessId pid = kv.first;  // kNullProcessId for the current process.
    ProcessMemoryDump* process_memory_dump = kv.second.get();
    TracedValue* traced_value = new TracedValue();
    scoped_refptr<ConvertableToTraceFormat> event_value(traced_value);
    process_memory_dump->AsValueInto(traced_value);
    traced_value->SetString("level_of_detail",
                            MemoryDumpLevelOfDetailToString(
                                pmd_async_state->req_args.level_of_detail));
    const char* const event_name =
        MemoryDumpTypeToString(pmd_async_state->req_args.dump_type);

    TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID(
        TRACE_EVENT_PHASE_MEMORY_DUMP,
        TraceLog::GetCategoryGroupEnabled(kTraceCategory), event_name,
        dump_guid, pid, kTraceEventNumArgs, kTraceEventArgNames,
        kTraceEventArgTypes, nullptr /* arg_values */, &event_value,
        TRACE_EVENT_FLAG_HAS_ID);
  }

  if (!pmd_async_state->callback.is_null()) {
    pmd_async_state->callback.Run(dump_guid, true /* success */);
    pmd_async_state->callback.Reset();
  }

  TRACE_EVENT_NESTABLE_ASYNC_END0(kTraceCategory, "ProcessMemoryDump",
                                  TRACE_ID_MANGLE(dump_guid));
}

// static
void MemoryDumpManager::AbortDumpLocked(
    MemoryDumpCallback callback,
    scoped_refptr<SingleThreadTaskRunner> task_runner,
    uint64_t dump_guid) {
  if (callback.is_null())
    return;  // There is nothing to NACK.

  // Post the callback even if we are already on the right thread to avoid
  // invoking the callback while holding the lock_.
  task_runner->PostTask(FROM_HERE,
                        Bind(callback, dump_guid, false /* success */));
}

void MemoryDumpManager::OnTraceLogEnabled() {
  bool enabled;
  TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTraceCategory, &enabled);
  if (!enabled)
    return;

  // Initialize the TraceLog for the current thread. This is to avoid that the
  // TraceLog memory dump provider is registered lazily in the PostTask() below
  // while the |lock_| is taken;
  TraceLog::GetInstance()->InitializeThreadLocalEventBufferIfSupported();

  // Spin-up the thread used to invoke unbound dump providers.
  scoped_ptr<Thread> dump_thread(new Thread("MemoryInfra"));
  if (!dump_thread->Start()) {
    LOG(ERROR) << "Failed to start the memory-infra thread for tracing";
    return;
  }

  AutoLock lock(lock_);

  DCHECK(delegate_);  // At this point we must have a delegate.

  scoped_refptr<StackFrameDeduplicator> stack_frame_deduplicator = nullptr;
  scoped_refptr<TypeNameDeduplicator> type_name_deduplicator = nullptr;

  if (heap_profiling_enabled_) {
    // If heap profiling is enabled, the stack frame deduplicator and type name
    // deduplicator will be in use. Add a metadata events to write the frames
    // and type IDs.
    stack_frame_deduplicator = new StackFrameDeduplicator;
    type_name_deduplicator = new TypeNameDeduplicator;
    TRACE_EVENT_API_ADD_METADATA_EVENT(
        "stackFrames", "stackFrames",
        scoped_refptr<ConvertableToTraceFormat>(stack_frame_deduplicator));
    TRACE_EVENT_API_ADD_METADATA_EVENT(
        "typeNames", "typeNames",
        scoped_refptr<ConvertableToTraceFormat>(type_name_deduplicator));
  }

  DCHECK(!dump_thread_);
  dump_thread_ = std::move(dump_thread);
  session_state_ = new MemoryDumpSessionState(stack_frame_deduplicator,
                                              type_name_deduplicator);

  for (auto it = dump_providers_.begin(); it != dump_providers_.end(); ++it) {
    it->disabled = false;
    it->consecutive_failures = 0;
  }

  subtle::NoBarrier_Store(&memory_tracing_enabled_, 1);

  // TODO(primiano): This is a temporary hack to disable periodic memory dumps
  // when running memory benchmarks until telemetry uses TraceConfig to
  // enable/disable periodic dumps. See crbug.com/529184 .
  if (!is_coordinator_ ||
      CommandLine::ForCurrentProcess()->HasSwitch(
          "enable-memory-benchmarking")) {
    return;
  }

  // Enable periodic dumps. At the moment the periodic support is limited to at
  // most one low-detail periodic dump and at most one high-detail periodic
  // dump. If both are specified the high-detail period must be an integer
  // multiple of the low-level one.
  g_periodic_dumps_count = 0;
  const TraceConfig trace_config =
      TraceLog::GetInstance()->GetCurrentTraceConfig();
  const TraceConfig::MemoryDumpConfig& config_list =
      trace_config.memory_dump_config();
  if (config_list.empty())
    return;

  uint32_t min_timer_period_ms = std::numeric_limits<uint32_t>::max();
  uint32_t heavy_dump_period_ms = 0;
  DCHECK_LE(config_list.size(), 2u);
  for (const TraceConfig::MemoryDumpTriggerConfig& config : config_list) {
    DCHECK(config.periodic_interval_ms);
    if (config.level_of_detail == MemoryDumpLevelOfDetail::DETAILED)
      heavy_dump_period_ms = config.periodic_interval_ms;
    min_timer_period_ms =
        std::min(min_timer_period_ms, config.periodic_interval_ms);
  }
  DCHECK_EQ(0u, heavy_dump_period_ms % min_timer_period_ms);
  g_heavy_dumps_rate = heavy_dump_period_ms / min_timer_period_ms;

  periodic_dump_timer_.Start(FROM_HERE,
                             TimeDelta::FromMilliseconds(min_timer_period_ms),
                             base::Bind(&RequestPeriodicGlobalDump));
}

void MemoryDumpManager::OnTraceLogDisabled() {
  subtle::NoBarrier_Store(&memory_tracing_enabled_, 0);
  scoped_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_|
  // or will deadlock (e.g., if ContinueAsyncProcessDump() tries to acquire it).
  periodic_dump_timer_.Stop();
  if (dump_thread)
    dump_thread->Stop();
}

uint64_t MemoryDumpManager::GetTracingProcessId() const {
  return delegate_->GetTracingProcessId();
}

MemoryDumpManager::MemoryDumpProviderInfo::MemoryDumpProviderInfo(
    MemoryDumpProvider* dump_provider,
    const char* name,
    const scoped_refptr<SingleThreadTaskRunner>& task_runner,
    const MemoryDumpProvider::Options& options)
    : dump_provider(dump_provider),
      name(name),
      task_runner(task_runner),
      options(options),
      consecutive_failures(0),
      disabled(false),
      unregistered(false) {}

MemoryDumpManager::MemoryDumpProviderInfo::~MemoryDumpProviderInfo() {}

bool MemoryDumpManager::MemoryDumpProviderInfo::operator<(
    const MemoryDumpProviderInfo& other) const {
  if (task_runner == other.task_runner)
    return dump_provider < other.dump_provider;
  // Ensure that unbound providers (task_runner == nullptr) always run last.
  return !(task_runner < other.task_runner);
}

MemoryDumpManager::ProcessMemoryDumpAsyncState::ProcessMemoryDumpAsyncState(
    MemoryDumpRequestArgs req_args,
    MemoryDumpProviderInfoSet::iterator next_dump_provider,
    const scoped_refptr<MemoryDumpSessionState>& session_state,
    MemoryDumpCallback callback,
    const scoped_refptr<SingleThreadTaskRunner>& dump_thread_task_runner)
    : req_args(req_args),
      next_dump_provider(next_dump_provider),
      session_state(session_state),
      callback(callback),
      callback_task_runner(MessageLoop::current()->task_runner()),
      dump_thread_task_runner(dump_thread_task_runner) {}

MemoryDumpManager::ProcessMemoryDumpAsyncState::~ProcessMemoryDumpAsyncState() {
}

ProcessMemoryDump* MemoryDumpManager::ProcessMemoryDumpAsyncState::
    GetOrCreateMemoryDumpContainerForProcess(ProcessId pid) {
  auto iter = process_dumps.find(pid);
  if (iter == process_dumps.end()) {
    scoped_ptr<ProcessMemoryDump> new_pmd(new ProcessMemoryDump(session_state));
    iter = process_dumps.insert(std::make_pair(pid, std::move(new_pmd))).first;
  }
  return iter->second.get();
}

}  // namespace trace_event
}  // namespace base
