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