OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "services/resource_coordinator/memory/coordinator/coordinator_impl.h" | 5 #include "services/resource_coordinator/memory/coordinator/coordinator_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 // static | 28 // static |
29 CoordinatorImpl* CoordinatorImpl::GetInstance() { | 29 CoordinatorImpl* CoordinatorImpl::GetInstance() { |
30 return g_coordinator_impl; | 30 return g_coordinator_impl; |
31 } | 31 } |
32 | 32 |
33 CoordinatorImpl::CoordinatorImpl(bool initialize_memory_dump_manager) | 33 CoordinatorImpl::CoordinatorImpl(bool initialize_memory_dump_manager) |
34 : failed_memory_dump_count_(0), | 34 : failed_memory_dump_count_(0), |
35 initialize_memory_dump_manager_(initialize_memory_dump_manager) { | 35 initialize_memory_dump_manager_(initialize_memory_dump_manager) { |
36 if (initialize_memory_dump_manager) { | 36 if (initialize_memory_dump_manager) { |
| 37 // TODO(primiano): the current state where the coordinator also creates a |
| 38 // client (ProcessLocalDumpManagerImpl) is contra-intuitive. BrowserMainLoop |
| 39 // should be doing this. |
37 ProcessLocalDumpManagerImpl::CreateInstance( | 40 ProcessLocalDumpManagerImpl::CreateInstance( |
38 ProcessLocalDumpManagerImpl::Config(this)); | 41 ProcessLocalDumpManagerImpl::Config(this, mojom::ProcessType::BROWSER)); |
39 base::trace_event::MemoryDumpManager::GetInstance()->set_tracing_process_id( | 42 base::trace_event::MemoryDumpManager::GetInstance()->set_tracing_process_id( |
40 mojom::kServiceTracingProcessId); | 43 mojom::kServiceTracingProcessId); |
41 } | 44 } |
42 g_coordinator_impl = this; | 45 g_coordinator_impl = this; |
43 } | 46 } |
44 | 47 |
45 CoordinatorImpl::~CoordinatorImpl() { | 48 CoordinatorImpl::~CoordinatorImpl() { |
46 g_coordinator_impl = nullptr; | 49 g_coordinator_impl = nullptr; |
47 } | 50 } |
48 | 51 |
(...skipping 25 matching lines...) Expand all Loading... |
74 base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED) { | 77 base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED) { |
75 for (const auto& request : queued_memory_dump_requests_) { | 78 for (const auto& request : queued_memory_dump_requests_) { |
76 if (request.args.level_of_detail == args.level_of_detail) { | 79 if (request.args.level_of_detail == args.level_of_detail) { |
77 VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix << " (" | 80 VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix << " (" |
78 << base::trace_event::MemoryDumpTypeToString(args.dump_type) | 81 << base::trace_event::MemoryDumpTypeToString(args.dump_type) |
79 << ") skipped because another dump request with the same " | 82 << ") skipped because another dump request with the same " |
80 "level of detail (" | 83 "level of detail (" |
81 << base::trace_event::MemoryDumpLevelOfDetailToString( | 84 << base::trace_event::MemoryDumpLevelOfDetailToString( |
82 args.level_of_detail) | 85 args.level_of_detail) |
83 << ") is already in the queue"; | 86 << ") is already in the queue"; |
84 callback.Run(args.dump_guid, false /* success */); | 87 callback.Run(args.dump_guid, false /* success */, |
| 88 nullptr /* global_memory_dump */); |
85 return; | 89 return; |
86 } | 90 } |
87 } | 91 } |
88 } | 92 } |
89 | 93 |
90 queued_memory_dump_requests_.emplace_back(args, callback); | 94 queued_memory_dump_requests_.emplace_back(args, callback); |
91 | 95 |
92 // If another dump is already in progress, this dump will automatically be | 96 // If another dump is already in progress, this dump will automatically be |
93 // scheduled when the other dump finishes. | 97 // scheduled when the other dump finishes. |
94 if (another_dump_already_in_progress) | 98 if (another_dump_already_in_progress) |
(...skipping 19 matching lines...) Expand all Loading... |
114 mojom::ProcessLocalDumpManager* process_manager) { | 118 mojom::ProcessLocalDumpManager* process_manager) { |
115 size_t num_deleted = process_managers_.erase(process_manager); | 119 size_t num_deleted = process_managers_.erase(process_manager); |
116 DCHECK(num_deleted == 1); | 120 DCHECK(num_deleted == 1); |
117 | 121 |
118 // Check if we are waiting for an ack from this process-local manager. | 122 // Check if we are waiting for an ack from this process-local manager. |
119 if (pending_process_managers_.find(process_manager) != | 123 if (pending_process_managers_.find(process_manager) != |
120 pending_process_managers_.end()) { | 124 pending_process_managers_.end()) { |
121 DCHECK(!queued_memory_dump_requests_.empty()); | 125 DCHECK(!queued_memory_dump_requests_.empty()); |
122 OnProcessMemoryDumpResponse( | 126 OnProcessMemoryDumpResponse( |
123 process_manager, queued_memory_dump_requests_.front().args.dump_guid, | 127 process_manager, queued_memory_dump_requests_.front().args.dump_guid, |
124 false /* success */, | 128 false /* success */, nullptr /* process_memory_dump */); |
125 base::Optional<base::trace_event::MemoryDumpCallbackResult>()); | |
126 } | 129 } |
127 } | 130 } |
128 | 131 |
129 void CoordinatorImpl::PerformNextQueuedGlobalMemoryDump() { | 132 void CoordinatorImpl::PerformNextQueuedGlobalMemoryDump() { |
130 DCHECK(!queued_memory_dump_requests_.empty()); | 133 DCHECK(!queued_memory_dump_requests_.empty()); |
131 const base::trace_event::MemoryDumpRequestArgs& args = | 134 const base::trace_event::MemoryDumpRequestArgs& args = |
132 queued_memory_dump_requests_.front().args; | 135 queued_memory_dump_requests_.front().args; |
133 | 136 |
134 // No need to treat the service process different than other processes. The | 137 // No need to treat the service process different than other processes. The |
135 // service process will register itself as a ProcessLocalDumpManager and will | 138 // service process will register itself as a ProcessLocalDumpManager and will |
136 // be treated like other process-local managers. | 139 // be treated like other process-local managers. |
137 pending_process_managers_.clear(); | 140 pending_process_managers_.clear(); |
138 failed_memory_dump_count_ = 0; | 141 failed_memory_dump_count_ = 0; |
139 for (const auto& key_value : process_managers_) { | 142 for (const auto& key_value : process_managers_) { |
140 pending_process_managers_.insert(key_value.first); | 143 pending_process_managers_.insert(key_value.first); |
141 auto callback = base::Bind(&CoordinatorImpl::OnProcessMemoryDumpResponse, | 144 auto callback = base::Bind(&CoordinatorImpl::OnProcessMemoryDumpResponse, |
142 base::Unretained(this), key_value.first); | 145 base::Unretained(this), key_value.first); |
143 key_value.second->RequestProcessMemoryDump(args, callback); | 146 key_value.second->RequestProcessMemoryDump(args, callback); |
144 } | 147 } |
145 // Run the callback in case there are no process-local managers. | 148 // Run the callback in case there are no process-local managers. |
146 FinalizeGlobalMemoryDumpIfAllManagersReplied(); | 149 FinalizeGlobalMemoryDumpIfAllManagersReplied(); |
147 } | 150 } |
148 | 151 |
149 void CoordinatorImpl::OnProcessMemoryDumpResponse( | 152 void CoordinatorImpl::OnProcessMemoryDumpResponse( |
150 mojom::ProcessLocalDumpManager* process_manager, | 153 mojom::ProcessLocalDumpManager* process_manager, |
151 uint64_t dump_guid, | 154 uint64_t dump_guid, |
152 bool success, | 155 bool success, |
153 const base::Optional<base::trace_event::MemoryDumpCallbackResult>& result) { | 156 mojom::ProcessMemoryDumpPtr process_memory_dump) { |
154 auto it = pending_process_managers_.find(process_manager); | 157 auto it = pending_process_managers_.find(process_manager); |
155 | 158 |
156 DCHECK(!queued_memory_dump_requests_.empty()); | 159 if (queued_memory_dump_requests_.empty() || |
157 if (queued_memory_dump_requests_.front().args.dump_guid != dump_guid || | 160 queued_memory_dump_requests_.front().args.dump_guid != dump_guid || |
158 it == pending_process_managers_.end()) { | 161 it == pending_process_managers_.end()) { |
159 VLOG(1) << "Received unexpected memory dump response: " << dump_guid; | 162 VLOG(1) << "Received unexpected memory dump response: " << dump_guid; |
160 return; | 163 return; |
161 } | 164 } |
| 165 if (process_memory_dump) { |
| 166 queued_memory_dump_requests_.front().process_memory_dumps.push_back( |
| 167 std::move(process_memory_dump)); |
| 168 } |
| 169 |
162 pending_process_managers_.erase(it); | 170 pending_process_managers_.erase(it); |
163 | 171 |
164 if (!success) { | 172 if (!success) { |
165 ++failed_memory_dump_count_; | 173 ++failed_memory_dump_count_; |
166 VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix | 174 VLOG(1) << base::trace_event::MemoryDumpManager::kLogPrefix |
167 << " failed because of NACK from provider"; | 175 << " failed because of NACK from provider"; |
168 } | 176 } |
| 177 |
169 FinalizeGlobalMemoryDumpIfAllManagersReplied(); | 178 FinalizeGlobalMemoryDumpIfAllManagersReplied(); |
170 } | 179 } |
171 | 180 |
172 void CoordinatorImpl::FinalizeGlobalMemoryDumpIfAllManagersReplied() { | 181 void CoordinatorImpl::FinalizeGlobalMemoryDumpIfAllManagersReplied() { |
173 if (pending_process_managers_.size() > 0) | 182 if (pending_process_managers_.size() > 0) |
174 return; | 183 return; |
175 | 184 |
176 DCHECK(!queued_memory_dump_requests_.empty()); | 185 if (queued_memory_dump_requests_.empty()) { |
177 { | 186 NOTREACHED(); |
178 const auto& callback = queued_memory_dump_requests_.front().callback; | 187 return; |
179 const bool global_success = failed_memory_dump_count_ == 0; | |
180 callback.Run(queued_memory_dump_requests_.front().args.dump_guid, | |
181 global_success); | |
182 } | 188 } |
| 189 |
| 190 // TODO(hjd,fmeawad): At this point the |process_memory_dumps| accumulated in |
| 191 // queued_memory_dump_requests_.front() should be normalized (merge |
| 192 // |extra_process_dump|, compute CMM) into a GlobalMemoryDumpPtr and passed |
| 193 // below. |
| 194 |
| 195 const auto& callback = queued_memory_dump_requests_.front().callback; |
| 196 const bool global_success = failed_memory_dump_count_ == 0; |
| 197 callback.Run(queued_memory_dump_requests_.front().args.dump_guid, |
| 198 global_success, nullptr /* global_memory_dump */); |
183 queued_memory_dump_requests_.pop_front(); | 199 queued_memory_dump_requests_.pop_front(); |
184 | 200 |
185 // Schedule the next queued dump (if applicable). | 201 // Schedule the next queued dump (if applicable). |
186 if (!queued_memory_dump_requests_.empty()) { | 202 if (!queued_memory_dump_requests_.empty()) { |
187 base::ThreadTaskRunnerHandle::Get()->PostTask( | 203 base::ThreadTaskRunnerHandle::Get()->PostTask( |
188 FROM_HERE, | 204 FROM_HERE, |
189 base::Bind(&CoordinatorImpl::PerformNextQueuedGlobalMemoryDump, | 205 base::Bind(&CoordinatorImpl::PerformNextQueuedGlobalMemoryDump, |
190 base::Unretained(this))); | 206 base::Unretained(this))); |
191 } | 207 } |
192 } | 208 } |
193 | 209 |
194 } // namespace memory_instrumentation | 210 } // namespace memory_instrumentation |
OLD | NEW |