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/coordination_unit/coordination_unit_impl
.h" | 5 #include "services/resource_coordinator/coordination_unit/coordination_unit_impl
.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <unordered_map> | 8 #include <unordered_map> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
12 #include "mojo/public/cpp/bindings/strong_binding.h" | 12 #include "mojo/public/cpp/bindings/strong_binding.h" |
| 13 #include "services/resource_coordinator/coordination_unit/coordination_unit_grap
h_observer.h" |
13 #include "services/resource_coordinator/public/cpp/coordination_unit_id.h" | 14 #include "services/resource_coordinator/public/cpp/coordination_unit_id.h" |
14 | 15 |
15 namespace resource_coordinator { | 16 namespace resource_coordinator { |
16 | 17 |
17 namespace { | 18 namespace { |
18 | 19 |
19 using CUIDMap = std::unordered_map<CoordinationUnitID, CoordinationUnitImpl*>; | 20 using CUIDMap = std::unordered_map<CoordinationUnitID, CoordinationUnitImpl*>; |
20 | 21 |
21 CUIDMap& g_cu_map() { | 22 CUIDMap& g_cu_map() { |
22 static CUIDMap* instance = new CUIDMap(); | 23 static CUIDMap* instance = new CUIDMap(); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 if (AddChild(child)) { | 151 if (AddChild(child)) { |
151 child->AddParent(this); | 152 child->AddParent(this); |
152 } | 153 } |
153 } | 154 } |
154 } | 155 } |
155 | 156 |
156 bool CoordinationUnitImpl::AddChild(CoordinationUnitImpl* child) { | 157 bool CoordinationUnitImpl::AddChild(CoordinationUnitImpl* child) { |
157 // We don't recalculate the policy here as policies are only dependent | 158 // We don't recalculate the policy here as policies are only dependent |
158 // on the current CU or its parents, not its children. In other words, | 159 // on the current CU or its parents, not its children. In other words, |
159 // policies only bubble down. | 160 // policies only bubble down. |
160 return children_.count(child) ? false : children_.insert(child).second; | 161 bool success = |
| 162 children_.count(child) ? false : children_.insert(child).second; |
| 163 |
| 164 if (success) { |
| 165 for (auto& observer : observers_) { |
| 166 observer.OnChildAdded(this, child); |
| 167 } |
| 168 } |
| 169 |
| 170 return success; |
161 } | 171 } |
162 | 172 |
163 void CoordinationUnitImpl::RemoveChild(const CoordinationUnitID& child_id) { | 173 void CoordinationUnitImpl::RemoveChild(const CoordinationUnitID& child_id) { |
164 auto child_iter = g_cu_map().find(child_id); | 174 auto child_iter = g_cu_map().find(child_id); |
165 if (child_iter == g_cu_map().end()) { | 175 if (child_iter == g_cu_map().end()) { |
166 return; | 176 return; |
167 } | 177 } |
168 | 178 |
169 CoordinationUnitImpl* child = child_iter->second; | 179 CoordinationUnitImpl* child = child_iter->second; |
170 if (!HasChild(child)) { | 180 if (!HasChild(child)) { |
171 return; | 181 return; |
172 } | 182 } |
173 | 183 |
174 DCHECK(child->id_ == child_id); | 184 DCHECK(child->id_ == child_id); |
175 DCHECK(child != this); | 185 DCHECK(child != this); |
176 | 186 |
177 if (RemoveChild(child)) { | 187 if (RemoveChild(child)) { |
178 child->RemoveParent(this); | 188 child->RemoveParent(this); |
179 } | 189 } |
180 } | 190 } |
181 | 191 |
182 bool CoordinationUnitImpl::RemoveChild(CoordinationUnitImpl* child) { | 192 bool CoordinationUnitImpl::RemoveChild(CoordinationUnitImpl* child) { |
183 size_t children_removed = children_.erase(child); | 193 size_t children_removed = children_.erase(child); |
184 return children_removed > 0; | 194 bool success = children_removed > 0; |
| 195 |
| 196 if (success) { |
| 197 for (auto& observer : observers_) { |
| 198 observer.OnChildRemoved(this, child); |
| 199 } |
| 200 } |
| 201 |
| 202 return success; |
185 } | 203 } |
186 | 204 |
187 void CoordinationUnitImpl::AddParent(CoordinationUnitImpl* parent) { | 205 void CoordinationUnitImpl::AddParent(CoordinationUnitImpl* parent) { |
188 DCHECK_EQ(0u, parents_.count(parent)); | 206 DCHECK_EQ(0u, parents_.count(parent)); |
189 parents_.insert(parent); | 207 parents_.insert(parent); |
190 | 208 |
| 209 for (auto& observer : observers_) { |
| 210 observer.OnParentAdded(this, parent); |
| 211 } |
| 212 |
191 RecalcCoordinationPolicy(); | 213 RecalcCoordinationPolicy(); |
192 } | 214 } |
193 | 215 |
194 void CoordinationUnitImpl::RemoveParent(CoordinationUnitImpl* parent) { | 216 void CoordinationUnitImpl::RemoveParent(CoordinationUnitImpl* parent) { |
195 size_t parents_removed = parents_.erase(parent); | 217 size_t parents_removed = parents_.erase(parent); |
196 DCHECK_EQ(1u, parents_removed); | 218 DCHECK_EQ(1u, parents_removed); |
197 | 219 |
| 220 // TODO(matthalp, oysteine) should this go before or |
| 221 // after RecalcCoordinationPolicy? |
| 222 for (auto& observer : observers_) { |
| 223 observer.OnParentRemoved(this, parent); |
| 224 } |
| 225 |
198 RecalcCoordinationPolicy(); | 226 RecalcCoordinationPolicy(); |
199 } | 227 } |
200 | 228 |
201 bool CoordinationUnitImpl::HasParent(CoordinationUnitImpl* unit) { | 229 bool CoordinationUnitImpl::HasParent(CoordinationUnitImpl* unit) { |
202 for (CoordinationUnitImpl* parent : parents_) { | 230 for (CoordinationUnitImpl* parent : parents_) { |
203 if (parent == unit || parent->HasParent(unit)) { | 231 if (parent == unit || parent->HasParent(unit)) { |
204 return true; | 232 return true; |
205 } | 233 } |
206 } | 234 } |
207 | 235 |
(...skipping 23 matching lines...) Expand all Loading... |
231 | 259 |
232 void CoordinationUnitImpl::UnregisterCoordinationPolicyCallback() { | 260 void CoordinationUnitImpl::UnregisterCoordinationPolicyCallback() { |
233 policy_callback_.reset(); | 261 policy_callback_.reset(); |
234 current_policy_.reset(); | 262 current_policy_.reset(); |
235 } | 263 } |
236 | 264 |
237 double CoordinationUnitImpl::GetCPUUsageForTesting() { | 265 double CoordinationUnitImpl::GetCPUUsageForTesting() { |
238 return kCPUUsageUnmeasuredForTesting; | 266 return kCPUUsageUnmeasuredForTesting; |
239 } | 267 } |
240 | 268 |
241 base::Value CoordinationUnitImpl::GetProperty(mojom::PropertyType property) { | 269 base::Value CoordinationUnitImpl::GetProperty( |
| 270 mojom::PropertyType property) const { |
242 auto value_it = property_store_.find(property); | 271 auto value_it = property_store_.find(property); |
243 | 272 |
244 return value_it != property_store_.end() ? value_it->second : base::Value(); | 273 return value_it != property_store_.end() ? value_it->second : base::Value(); |
245 } | 274 } |
246 | 275 |
247 void CoordinationUnitImpl::ClearProperty(mojom::PropertyType property) { | 276 void CoordinationUnitImpl::ClearProperty(mojom::PropertyType property) { |
248 property_store_.erase(property); | 277 property_store_.erase(property); |
249 } | 278 } |
250 | 279 |
251 void CoordinationUnitImpl::SetProperty(mojom::PropertyPtr property) { | 280 void CoordinationUnitImpl::SetProperty(mojom::PropertyPtr property) { |
252 SetProperty(property->property, *property->value); | 281 SetProperty(property->property, *property->value); |
253 } | 282 } |
254 | 283 |
255 void CoordinationUnitImpl::SetProperty(mojom::PropertyType property, | 284 void CoordinationUnitImpl::SetProperty(mojom::PropertyType property, |
256 base::Value value) { | 285 base::Value value) { |
257 // setting a property with an empty value is effectively clearing the | 286 // setting a property with an empty value is effectively clearing the |
258 // value from storage | 287 // value from storage |
259 if (value.IsType(base::Value::Type::NONE)) { | 288 if (value.IsType(base::Value::Type::NONE)) { |
260 ClearProperty(property); | 289 ClearProperty(property); |
261 return; | 290 return; |
262 } | 291 } |
263 | 292 |
264 property_store_[property] = value; | 293 property_store_[property] = value; |
| 294 |
| 295 for (auto& observer : observers_) { |
| 296 observer.OnPropertyChanged(this, property); |
| 297 } |
| 298 } |
| 299 |
| 300 void CoordinationUnitImpl::WillBeDestroyed() { |
| 301 for (auto& observer : observers_) { |
| 302 observer.OnCoordinationUnitWillBeDestroyed(this); |
| 303 } |
| 304 } |
| 305 |
| 306 void CoordinationUnitImpl::AddObserver( |
| 307 CoordinationUnitGraphObserver* observer) { |
| 308 observers_.AddObserver(observer); |
| 309 } |
| 310 |
| 311 void CoordinationUnitImpl::RemoveObserver( |
| 312 CoordinationUnitGraphObserver* observer) { |
| 313 observers_.RemoveObserver(observer); |
265 } | 314 } |
266 | 315 |
267 } // namespace resource_coordinator | 316 } // namespace resource_coordinator |
OLD | NEW |