// 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.

#ifndef BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_
#define BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_

#include <map>
#include <memory>
#include <unordered_set>
#include <vector>

#include "base/atomicops.h"
#include "base/containers/hash_tables.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
#include "base/trace_event/memory_allocator_dump.h"
#include "base/trace_event/memory_dump_provider_info.h"
#include "base/trace_event/memory_dump_request_args.h"
#include "base/trace_event/process_memory_dump.h"
#include "base/trace_event/trace_event.h"
#include "starboard/types.h"

#if !defined(STARBOARD)

namespace base {

class SequencedTaskRunner;
class SingleThreadTaskRunner;
class Thread;

namespace trace_event {

class MemoryDumpProvider;

// This is the interface exposed to the rest of the codebase to deal with
// memory tracing. The main entry point for clients is represented by
// RequestDumpPoint(). The extension by Un(RegisterDumpProvider).
class BASE_EXPORT MemoryDumpManager {
 public:
  using RequestGlobalDumpFunction =
      RepeatingCallback<void(MemoryDumpType, MemoryDumpLevelOfDetail)>;

  static const char* const kTraceCategory;

  // This value is returned as the tracing id of the child processes by
  // GetTracingProcessId() when tracing is not enabled.
  static const uint64_t kInvalidTracingProcessId;

  static MemoryDumpManager* GetInstance();
  static std::unique_ptr<MemoryDumpManager> CreateInstanceForTesting();

  // Invoked once per process to listen to trace begin / end events.
  // Initialization can happen after (Un)RegisterMemoryDumpProvider() calls
  // and the MemoryDumpManager guarantees to support this.
  // On the other side, the MemoryDumpManager will not be fully operational
  // (any CreateProcessDump() will return a failure) until initialized.
  // Arguments:
  //  is_coordinator: True when current process coordinates the periodic dump
  //      triggering.
  //  request_dump_function: Function to invoke a global dump. Global dump
  //      involves embedder-specific behaviors like multiprocess handshaking.
  //      TODO(primiano): this is only required to trigger global dumps from
  //      the scheduler. Should be removed once they are both moved out of base.
  void Initialize(RequestGlobalDumpFunction request_dump_function,
                  bool is_coordinator);

  // (Un)Registers a MemoryDumpProvider instance.
  // Args:
  //  - mdp: the MemoryDumpProvider instance to be registered. MemoryDumpManager
  //      does NOT take memory ownership of |mdp|, which is expected to either
  //      be a singleton or unregister itself.
  //  - name: a friendly name (duplicates allowed). Used for debugging and
  //      run-time profiling of memory-infra internals. Must be a long-lived
  //      C string.
  //  - task_runner: either a SingleThreadTaskRunner or SequencedTaskRunner. All
  //      the calls to |mdp| will be run on the given |task_runner|. If passed
  //      null |mdp| should be able to handle calls on arbitrary threads.
  //  - options: extra optional arguments. See memory_dump_provider.h.
  void RegisterDumpProvider(MemoryDumpProvider* mdp,
                            const char* name,
                            scoped_refptr<SingleThreadTaskRunner> task_runner);
  void RegisterDumpProvider(MemoryDumpProvider* mdp,
                            const char* name,
                            scoped_refptr<SingleThreadTaskRunner> task_runner,
                            MemoryDumpProvider::Options options);
  void RegisterDumpProviderWithSequencedTaskRunner(
      MemoryDumpProvider* mdp,
      const char* name,
      scoped_refptr<SequencedTaskRunner> task_runner,
      MemoryDumpProvider::Options options);
  void UnregisterDumpProvider(MemoryDumpProvider* mdp);

  // Unregisters an unbound dump provider and takes care about its deletion
  // asynchronously. Can be used only for for dump providers with no
  // task-runner affinity.
  // This method takes ownership of the dump provider and guarantees that:
  //  - The |mdp| will be deleted at some point in the near future.
  //  - Its deletion will not happen concurrently with the OnMemoryDump() call.
  // Note that OnMemoryDump() calls can still happen after this method returns.
  void UnregisterAndDeleteDumpProviderSoon(
      std::unique_ptr<MemoryDumpProvider> mdp);

  // Prepare MemoryDumpManager for CreateProcessDump() calls for tracing-related
  // modes (i.e. |level_of_detail| != SUMMARY_ONLY).
  // Also initializes the scheduler with the given config.
  void SetupForTracing(const TraceConfig::MemoryDumpConfig&);

  // Tear-down tracing related state.
  // Non-tracing modes (e.g. SUMMARY_ONLY) will continue to work.
  void TeardownForTracing();

  // Creates a memory dump for the current process and appends it to the trace.
  // |callback| will be invoked asynchronously upon completion on the same
  // thread on which CreateProcessDump() was called. This method should only be
  // used by the memory-infra service while creating a global memory dump.
  void CreateProcessDump(const MemoryDumpRequestArgs& args,
                         const ProcessMemoryDumpCallback& callback);

  // Lets tests see if a dump provider is registered.
  bool IsDumpProviderRegisteredForTesting(MemoryDumpProvider*);

  // Returns a unique id for identifying the processes. The id can be
  // retrieved by child processes only when tracing is enabled. This is
  // intended to express cross-process sharing of memory dumps on the
  // child-process side, without having to know its own child process id.
  uint64_t GetTracingProcessId() const { return tracing_process_id_; }
  void set_tracing_process_id(uint64_t tracing_process_id) {
    tracing_process_id_ = tracing_process_id;
  }

  // Returns the name for a the allocated_objects dump. Use this to declare
  // suballocator dumps from other dump providers.
  // It will return nullptr if there is no dump provider for the system
  // allocator registered (which is currently the case for Mac OS).
  const char* system_allocator_pool_name() const {
    return kSystemAllocatorPoolName;
  };

  // When set to true, calling |RegisterMemoryDumpProvider| is a no-op.
  void set_dumper_registrations_ignored_for_testing(bool ignored) {
    dumper_registrations_ignored_for_testing_ = ignored;
  }

 private:
  friend std::default_delete<MemoryDumpManager>;  // For the testing instance.
  friend struct DefaultSingletonTraits<MemoryDumpManager>;
  friend class MemoryDumpManagerTest;
  FRIEND_TEST_ALL_PREFIXES(MemoryDumpManagerTest,
                           NoStackOverflowWithTooManyMDPs);

  // Holds the state of a process memory dump that needs to be carried over
  // across task runners in order to fulfill an asynchronous CreateProcessDump()
  // request. At any time exactly one task runner owns a
  // ProcessMemoryDumpAsyncState.
  struct ProcessMemoryDumpAsyncState {
    ProcessMemoryDumpAsyncState(
        MemoryDumpRequestArgs req_args,
        const MemoryDumpProviderInfo::OrderedSet& dump_providers,
        ProcessMemoryDumpCallback callback,
        scoped_refptr<SequencedTaskRunner> dump_thread_task_runner);
    ~ProcessMemoryDumpAsyncState();

    // A ProcessMemoryDump to collect data from MemoryDumpProviders.
    std::unique_ptr<ProcessMemoryDump> process_memory_dump;

    // The arguments passed to the initial CreateProcessDump() request.
    const MemoryDumpRequestArgs req_args;

    // An ordered sequence of dump providers that have to be invoked to complete
    // the dump. This is a copy of |dump_providers_| at the beginning of a dump
    // and becomes empty at the end, when all dump providers have been invoked.
    std::vector<scoped_refptr<MemoryDumpProviderInfo>> pending_dump_providers;

    // Callback passed to the initial call to CreateProcessDump().
    ProcessMemoryDumpCallback callback;

    // The thread on which FinishAsyncProcessDump() (and hence |callback|)
    // should be invoked. This is the thread on which the initial
    // CreateProcessDump() request was called.
    const scoped_refptr<SingleThreadTaskRunner> callback_task_runner;

    // The thread on which unbound dump providers should be invoked.
    // This is essentially |dump_thread_|.task_runner() but needs to be kept
    // as a separate variable as it needs to be accessed by arbitrary dumpers'
    // threads outside of the lock_ to avoid races when disabling tracing.
    // It is immutable for all the duration of a tracing session.
    const scoped_refptr<SequencedTaskRunner> dump_thread_task_runner;

   private:
    DISALLOW_COPY_AND_ASSIGN(ProcessMemoryDumpAsyncState);
  };

  static const int kMaxConsecutiveFailuresCount;
  static const char* const kSystemAllocatorPoolName;

  MemoryDumpManager();
  virtual ~MemoryDumpManager();

  static void SetInstanceForTesting(MemoryDumpManager* instance);

  // Lazily initializes dump_thread_ and returns its TaskRunner.
  scoped_refptr<base::SequencedTaskRunner> GetOrCreateBgTaskRunnerLocked();

  // Calls InvokeOnMemoryDump() for the each MDP that belongs to the current
  // task runner and switches to the task runner of the next MDP. Handles
  // failures in MDP and thread hops, and always calls FinishAsyncProcessDump()
  // at the end.
  void ContinueAsyncProcessDump(
      ProcessMemoryDumpAsyncState* owned_pmd_async_state);

  // Invokes OnMemoryDump() of the given MDP. Should be called on the MDP task
  // runner.
  void InvokeOnMemoryDump(MemoryDumpProviderInfo* mdpinfo,
                          ProcessMemoryDump* pmd);

  void FinishAsyncProcessDump(
      std::unique_ptr<ProcessMemoryDumpAsyncState> pmd_async_state);

  // Helper for RegierDumpProvider* functions.
  void RegisterDumpProviderInternal(
      MemoryDumpProvider* mdp,
      const char* name,
      scoped_refptr<SequencedTaskRunner> task_runner,
      const MemoryDumpProvider::Options& options);

  // Helper for the public UnregisterDumpProvider* functions.
  void UnregisterDumpProviderInternal(MemoryDumpProvider* mdp,
                                      bool take_mdp_ownership_and_delete_async);

  bool can_request_global_dumps() const {
    return !request_dump_function_.is_null();
  }

  // An ordered set of registered MemoryDumpProviderInfo(s), sorted by task
  // runner affinity (MDPs belonging to the same task runners are adjacent).
  MemoryDumpProviderInfo::OrderedSet dump_providers_;

  // Function provided by the embedder to handle global dump requests.
  RequestGlobalDumpFunction request_dump_function_;

  // True when current process coordinates the periodic dump triggering.
  bool is_coordinator_;

  // Protects from concurrent accesses to the local state, eg: to guard against
  // disabling logging while dumping on another thread.
  Lock lock_;

  // Thread used for MemoryDumpProviders which don't specify a task runner
  // affinity.
  std::unique_ptr<Thread> dump_thread_;

  // The unique id of the child process. This is created only for tracing and is
  // expected to be valid only when tracing is enabled.
  uint64_t tracing_process_id_;

  // When true, calling |RegisterMemoryDumpProvider| is a no-op.
  bool dumper_registrations_ignored_for_testing_;

  DISALLOW_COPY_AND_ASSIGN(MemoryDumpManager);
};

}  // namespace trace_event
}  // namespace base

#endif  // #if !defined(STARBOARD)

#endif  // BASE_TRACE_EVENT_MEMORY_DUMP_MANAGER_H_
