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

Side by Side Diff: services/memory_instrumentation/coordinator_impl.cc

Issue 2693063002: Renamed /services/memory_infrastructure to /services/resource_coordinator (Closed)
Patch Set: Review fix Created 3 years, 10 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 unified diff | Download patch
OLDNEW
(Empty)
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 #include "services/memory_instrumentation/coordinator_impl.h"
6
7 #include "base/bind_helpers.h"
8 #include "base/lazy_instance.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/threading/thread_task_runner_handle.h"
13 #include "base/trace_event/memory_dump_manager.h"
14 #include "base/trace_event/memory_dump_request_args.h"
15 #include "services/memory_instrumentation/public/interfaces/memory_instrumentati on.mojom.h"
16
17 namespace memory_instrumentation {
18
19 namespace {
20
21 base::LazyInstance<CoordinatorImpl>::Leaky g_coordinator =
22 LAZY_INSTANCE_INITIALIZER;
23
24 } // namespace
25
26 // static
27 CoordinatorImpl* CoordinatorImpl::GetInstance() {
28 return g_coordinator.Pointer();
29 }
30
31 // TODO(chiniforooshan): Initialize the global MemoryDumpManager instance here.
32 // This is how the global MemoryDumpManager gets a reference to the delegate on
33 // the service (read the browser) process for service process memory dumps. This
34 // can be done when the delegate implementation is landed.
35 CoordinatorImpl::CoordinatorImpl()
36 : failed_memory_dump_count_(0) {}
37
38 CoordinatorImpl::~CoordinatorImpl() {}
39
40 void CoordinatorImpl::BindCoordinatorRequest(
41 mojom::CoordinatorRequest request) {
42 bindings_.AddBinding(this, std::move(request));
43 }
44
45 CoordinatorImpl::QueuedMemoryDumpRequest::QueuedMemoryDumpRequest(
46 const base::trace_event::MemoryDumpRequestArgs args,
47 const RequestGlobalMemoryDumpCallback callback)
48 : args(args), callback(callback) {}
49
50 CoordinatorImpl::QueuedMemoryDumpRequest::~QueuedMemoryDumpRequest() {}
51
52 void CoordinatorImpl::RequestGlobalMemoryDump(
53 const base::trace_event::MemoryDumpRequestArgs& args,
54 const RequestGlobalMemoryDumpCallback& callback) {
55 DCHECK(thread_checker_.CalledOnValidThread());
56
57 bool another_dump_already_in_progress = !queued_memory_dump_requests_.empty();
58
59 // If this is a periodic memory dump request and there already is another
60 // request in the queue with the same level of detail, there's no point in
61 // enqueuing this request.
62 if (another_dump_already_in_progress &&
63 args.dump_type == base::trace_event::MemoryDumpType::PERIODIC_INTERVAL) {
64 for (const auto& request : queued_memory_dump_requests_) {
65 if (request.args.level_of_detail == args.level_of_detail) {
66 VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix << " ("
67 << base::trace_event::MemoryDumpTypeToString(args.dump_type)
68 << ") skipped because another dump request with the same "
69 "level of detail ("
70 << base::trace_event::MemoryDumpLevelOfDetailToString(
71 args.level_of_detail)
72 << ") is already in the queue";
73 callback.Run(args.dump_guid, false /* success */);
74 return;
75 }
76 }
77 }
78
79 queued_memory_dump_requests_.emplace_back(args, callback);
80
81 // If another dump is already in progress, this dump will automatically be
82 // scheduled when the other dump finishes.
83 if (another_dump_already_in_progress)
84 return;
85
86 PerformNextQueuedGlobalMemoryDump();
87 }
88
89 void CoordinatorImpl::RegisterProcessLocalDumpManager(
90 mojom::ProcessLocalDumpManagerPtr process_manager) {
91 DCHECK(thread_checker_.CalledOnValidThread());
92
93 process_manager.set_connection_error_handler(
94 base::Bind(&CoordinatorImpl::UnregisterProcessLocalDumpManager,
95 base::Unretained(this),
96 process_manager.get()));
97 auto result = process_managers_.insert(
98 std::make_pair<mojom::ProcessLocalDumpManager*,
99 mojom::ProcessLocalDumpManagerPtr>(
100 process_manager.get(), std::move(process_manager)));
101 DCHECK(result.second);
102 }
103
104 void CoordinatorImpl::UnregisterProcessLocalDumpManager(
105 mojom::ProcessLocalDumpManager* process_manager) {
106 DCHECK(process_managers_.erase(process_manager) == 1);
107
108 // Check if we are waiting for an ack from this process-local manager.
109 if (pending_process_managers_.find(process_manager) !=
110 pending_process_managers_.end()) {
111 DCHECK(!queued_memory_dump_requests_.empty());
112 OnProcessMemoryDumpResponse(
113 process_manager,
114 queued_memory_dump_requests_.front().args.dump_guid,
115 false /* success */);
116 }
117 }
118
119 void CoordinatorImpl::PerformNextQueuedGlobalMemoryDump() {
120 DCHECK(!queued_memory_dump_requests_.empty());
121 const base::trace_event::MemoryDumpRequestArgs& args =
122 queued_memory_dump_requests_.front().args;
123
124 // No need to treat the service process different than other processes. The
125 // service process will register itself as a ProcessLocalDumpManager and will
126 // be treated like other process-local managers.
127 pending_process_managers_.clear();
128 failed_memory_dump_count_ = 0;
129 for (const auto& key_value : process_managers_) {
130 pending_process_managers_.insert(key_value.first);
131 key_value.second->RequestProcessMemoryDump(
132 args,
133 base::Bind(&CoordinatorImpl::OnProcessMemoryDumpResponse,
134 base::Unretained(this),
135 key_value.first));
136 }
137 // Run the callback in case there are no process-local managers.
138 FinalizeGlobalMemoryDumpIfAllManagersReplied();
139 }
140
141 void CoordinatorImpl::OnProcessMemoryDumpResponse(
142 mojom::ProcessLocalDumpManager* process_manager,
143 uint64_t dump_guid,
144 bool success) {
145 auto it = pending_process_managers_.find(process_manager);
146
147 DCHECK(!queued_memory_dump_requests_.empty());
148 if (queued_memory_dump_requests_.front().args.dump_guid != dump_guid ||
149 it == pending_process_managers_.end()) {
150 VLOG(1) << "Received unexpected memory dump response: " << dump_guid;
151 return;
152 }
153 pending_process_managers_.erase(it);
154
155 if (!success) {
156 ++failed_memory_dump_count_;
157 VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix
158 << " failed because of NACK from provider";
159 }
160 FinalizeGlobalMemoryDumpIfAllManagersReplied();
161 }
162
163 void CoordinatorImpl::FinalizeGlobalMemoryDumpIfAllManagersReplied() {
164 if (pending_process_managers_.size() > 0)
165 return;
166
167 DCHECK(!queued_memory_dump_requests_.empty());
168 {
169 const auto& callback = queued_memory_dump_requests_.front().callback;
170 const bool global_success = failed_memory_dump_count_ == 0;
171 callback.Run(queued_memory_dump_requests_.front().args.dump_guid,
172 global_success);
173 }
174 queued_memory_dump_requests_.pop_front();
175
176 // Schedule the next queued dump (if applicable).
177 if (!queued_memory_dump_requests_.empty()) {
178 base::ThreadTaskRunnerHandle::Get()->PostTask(
179 FROM_HERE,
180 base::Bind(
181 &CoordinatorImpl::PerformNextQueuedGlobalMemoryDump,
182 base::Unretained(this)));
183 }
184 }
185
186 } // namespace memory_instrumentation
OLDNEW
« no previous file with comments | « services/memory_instrumentation/coordinator_impl.h ('k') | services/memory_instrumentation/coordinator_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698