1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_INSTRUMENTATION_CLIENT_PROCESS_IMPL_H_
6 #define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_INSTRUMENTATION_CLIENT_PROCESS_IMPL_H_
7 
8 #include "base/compiler_specific.h"
9 #include "base/component_export.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/synchronization/lock.h"
12 #include "base/trace_event/memory_dump_manager.h"
13 #include "base/trace_event/memory_dump_request_args.h"
14 #include "mojo/public/cpp/bindings/pending_receiver.h"
15 #include "mojo/public/cpp/bindings/pending_remote.h"
16 #include "mojo/public/cpp/bindings/receiver.h"
17 #include "mojo/public/cpp/bindings/remote.h"
18 #include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h"
19 
20 namespace memory_instrumentation {
21 
22 class TracingObserver;
23 
24 // This is the bridge between MemoryDumpManager and the Coordinator service.
25 // This indirection is needed to avoid a dependency from //base, where
26 // MemoryDumpManager lives, to //services, where the Coordinator service lives.
27 //
28 // This cannot just be implemented by the Coordinator service, because there is
29 // no Coordinator service in child processes. So, in a child process, the
30 // local dump manager remotely connects to the Coordinator service. In the
31 // browser process, it locally connects to the Coordinator service.
COMPONENT_EXPORT(RESOURCE_COORDINATOR_PUBLIC_MEMORY_INSTRUMENTATION)32 class COMPONENT_EXPORT(RESOURCE_COORDINATOR_PUBLIC_MEMORY_INSTRUMENTATION)
33     ClientProcessImpl : public mojom::ClientProcess {
34  public:
35   static void CreateInstance(
36       mojo::PendingReceiver<mojom::ClientProcess> receiver,
37       mojo::PendingRemote<mojom::Coordinator> coordinator,
38       bool is_browser_process = false);
39 
40  private:
41   friend std::default_delete<ClientProcessImpl>;  // For testing
42   friend class MemoryTracingIntegrationTest;
43 
44   ClientProcessImpl(mojo::PendingReceiver<mojom::ClientProcess> receiver,
45                     mojo::PendingRemote<mojom::Coordinator> coordinator,
46                     bool is_browser_process,
47                     bool initialize_memory_instrumentation);
48   ~ClientProcessImpl() override;
49 
50   // Implements base::trace_event::MemoryDumpManager::RequestGlobalDumpCallback.
51   // This function will be called by the MemoryDumpScheduler::OnTick.
52   void RequestGlobalMemoryDump_NoCallback(
53       base::trace_event::MemoryDumpType type,
54       base::trace_event::MemoryDumpLevelOfDetail level_of_detail);
55 
56   // mojom::ClientProcess implementation. The Coordinator calls this.
57   void RequestChromeMemoryDump(
58       const base::trace_event::MemoryDumpRequestArgs& args,
59       RequestChromeMemoryDumpCallback callback) override;
60 
61   // Callback passed to base::MemoryDumpManager::CreateProcessDump().
62   void OnChromeMemoryDumpDone(
63       bool success,
64       uint64_t dump_guid,
65       std::unique_ptr<base::trace_event::ProcessMemoryDump>);
66 
67   // mojom::ClientProcess implementation. The Coordinator calls this.
68   void RequestOSMemoryDump(mojom::MemoryMapOption mmap_option,
69                            const std::vector<base::ProcessId>& ids,
70                            RequestOSMemoryDumpCallback callback) override;
71 
72   struct OSMemoryDumpArgs {
73     OSMemoryDumpArgs();
74     OSMemoryDumpArgs(OSMemoryDumpArgs&&);
75     ~OSMemoryDumpArgs();
76     mojom::MemoryMapOption mmap_option;
77     std::vector<base::ProcessId> pids;
78     RequestOSMemoryDumpCallback callback;
79   };
80   void PerformOSMemoryDump(OSMemoryDumpArgs args);
81 
82   // Map containing pending chrome memory callbacks indexed by dump guid.
83   // This must be destroyed after |binding_|.
84   std::map<uint64_t, RequestChromeMemoryDumpCallback> pending_chrome_callbacks_;
85 
86   // On macOS, we must wait for the most recent RequestChromeMemoryDumpCallback
87   // to complete before running the OS calculations. The key to this map is the
88   // dump_guid of that RequestChromeMemoryDumpCallback, the value a vector of
89   // callbacks to calculate and run. For more details, see
90   // https://bugs.chromium.org/p/chromium/issues/detail?id=812346#c16.
91   std::map<uint64_t, std::vector<OSMemoryDumpArgs>>
92       delayed_os_memory_dump_callbacks_;
93   base::Optional<uint64_t> most_recent_chrome_memory_dump_guid_;
94 
95   mojo::Receiver<mojom::ClientProcess> receiver_;
96   mojo::Remote<mojom::Coordinator> coordinator_;
97   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
98 
99   // TODO(crbug.com/728199): The observer is only used to setup and tear down
100   // MemoryDumpManager in each process. Setting up MemoryDumpManager should
101   // be moved away from TracingObserver.
102   std::unique_ptr<TracingObserver> tracing_observer_;
103 
104   DISALLOW_COPY_AND_ASSIGN(ClientProcessImpl);
105 };
106 
107 }  // namespace memory_instrumentation
108 
109 #endif  // SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MEMORY_INSTRUMENTATION_CLIENT_PROCESS_IMPL_H_
110