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

Side by Side Diff: athena/resource_manager/resource_manager_impl.cc

Issue 588823002: A visibile to invisible state change will also release memory and should therefore wait as an unloa… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: nits Created 6 years, 3 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "athena/resource_manager/public/resource_manager.h" 5 #include "athena/resource_manager/public/resource_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <vector> 8 #include <vector>
9 9
10 #include "athena/activity/public/activity.h" 10 #include "athena/activity/public/activity.h"
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 74
75 // WindowListProviderObserver: 75 // WindowListProviderObserver:
76 virtual void OnWindowStackingChanged() OVERRIDE; 76 virtual void OnWindowStackingChanged() OVERRIDE;
77 virtual void OnWindowRemoved(aura::Window* removed_window, 77 virtual void OnWindowRemoved(aura::Window* removed_window,
78 int index) OVERRIDE; 78 int index) OVERRIDE;
79 79
80 private: 80 private:
81 // Manage the resources for our activities. 81 // Manage the resources for our activities.
82 void ManageResource(); 82 void ManageResource();
83 83
84 // Check that the visibility of activities is properly set.
85 void UpdateVisibilityStates();
86
87 // Check if activities can be unloaded to reduce memory pressure.
88 void TryToUnloadAnActivity();
89
84 // Order our activity list to the order of activities of the stream. 90 // Order our activity list to the order of activities of the stream.
85 // TODO(skuhne): Once the ActivityManager is responsible to create this list 91 // TODO(skuhne): Once the ActivityManager is responsible to create this list
86 // for us, we can remove this code here. 92 // for us, we can remove this code here.
87 void UpdateActivityOrder(); 93 void UpdateActivityOrder();
88 94
95 // Resources were released and a quiet period is needed before we release
96 // more since it takes a while to trickle through the system.
97 void OnResourcesReleased();
98
99 // The memory pressure has increased, previously applied measures did not show
100 // effect and immediate action is required.
101 void OnMemoryPressureIncreased();
102
103 // Returns true when the previous memory release was long enough ago to try
104 // unloading another activity.
105 bool AllowedToUnloadActivity();
106
89 // The sorted (new(front) -> old(back)) activity list. 107 // The sorted (new(front) -> old(back)) activity list.
90 // TODO(skuhne): Once the ActivityManager is responsible to create this list 108 // TODO(skuhne): Once the ActivityManager is responsible to create this list
91 // for us, we can remove this code here. 109 // for us, we can remove this code here.
92 std::vector<Activity*> activity_list_; 110 std::vector<Activity*> activity_list_;
93 111
94 // The resource manager delegate. 112 // The resource manager delegate.
95 scoped_ptr<ResourceManagerDelegate> delegate_; 113 scoped_ptr<ResourceManagerDelegate> delegate_;
96 114
97 // Keeping a reference to the current memory pressure. 115 // Keeping a reference to the current memory pressure.
98 MemoryPressureObserver::MemoryPressure current_memory_pressure_; 116 MemoryPressureObserver::MemoryPressure current_memory_pressure_;
99 117
100 // The memory pressure notifier. 118 // The memory pressure notifier.
101 scoped_ptr<MemoryPressureNotifier> memory_pressure_notifier_; 119 scoped_ptr<MemoryPressureNotifier> memory_pressure_notifier_;
102 120
103 // A ref counter. As long as not 0, the management is on hold. 121 // A ref counter. As long as not 0, the management is on hold.
104 int pause_; 122 int pause_;
105 123
106 // If true, a command came in while the resource manager was paused. 124 // If true, a command came in while the resource manager was paused.
107 bool queued_command_; 125 bool queued_command_;
108 126
109 // Used by ManageResource() to determine an activity state change while it 127 // Used by ManageResource() to determine an activity state change while it
110 // changes Activity properties. 128 // changes Activity properties.
111 bool activity_order_changed_; 129 bool activity_order_changed_;
112 130
113 // True if in overview mode - activity order changes will be ignored if true 131 // True if in overview mode - activity order changes will be ignored if true
114 // and postponed till after the overview mode is ending. 132 // and postponed till after the overview mode is ending.
115 bool in_overview_mode_; 133 bool in_overview_mode_;
116 134
117 // True if we are in split view mode. 135 // True if we are in split view mode.
118 bool in_splitview_mode_; 136 bool in_split_view_mode_;
119 137
120 // The last time the resource manager was called to release resources. 138 // The last time the resource manager was called to release resources.
121 // Avoid too aggressive resource de-allocation by enforcing a wait time of 139 // Avoid too aggressive resource de-allocation by enforcing a wait time of
122 // |wait_time_for_resource_deallocation_| between executed calls. 140 // |wait_time_for_resource_deallocation_| between executed calls.
123 base::Time next_resource_management_time_; 141 base::Time next_resource_management_time_;
124 142
125 // The wait time between two resource managing executions. 143 // The wait time between two resource managing executions.
126 base::TimeDelta wait_time_for_resource_deallocation_; 144 base::TimeDelta wait_time_for_resource_deallocation_;
127 145
128 DISALLOW_COPY_AND_ASSIGN(ResourceManagerImpl); 146 DISALLOW_COPY_AND_ASSIGN(ResourceManagerImpl);
129 }; 147 };
130 148
131 namespace { 149 namespace {
132 ResourceManagerImpl* instance = NULL; 150 ResourceManagerImpl* instance = NULL;
133 151
134 // We allow this many activities to be visible. All others must be at state of 152 // We allow this many activities to be visible. All others must be at state of
135 // invisible or below. 153 // invisible or below.
136 const int kMaxVisibleActivities = 3; 154 const int kMaxVisibleActivities = 3;
137 155
138 } // namespace 156 } // namespace
139 157
140 ResourceManagerImpl::ResourceManagerImpl(ResourceManagerDelegate* delegate) 158 ResourceManagerImpl::ResourceManagerImpl(ResourceManagerDelegate* delegate)
141 : delegate_(delegate), 159 : delegate_(delegate),
142 current_memory_pressure_(MemoryPressureObserver::MEMORY_PRESSURE_UNKNOWN), 160 current_memory_pressure_(MemoryPressureObserver::MEMORY_PRESSURE_UNKNOWN),
143 memory_pressure_notifier_(new MemoryPressureNotifier(this)), 161 memory_pressure_notifier_(new MemoryPressureNotifier(this)),
144 pause_(false), 162 pause_(false),
145 queued_command_(false), 163 queued_command_(false),
146 activity_order_changed_(false), 164 activity_order_changed_(false),
147 in_overview_mode_(false), 165 in_overview_mode_(false),
148 in_splitview_mode_(false), 166 in_split_view_mode_(false),
149 next_resource_management_time_(base::Time::Now()), 167 next_resource_management_time_(base::Time::Now()),
150 wait_time_for_resource_deallocation_(base::TimeDelta::FromMilliseconds( 168 wait_time_for_resource_deallocation_(base::TimeDelta::FromMilliseconds(
151 delegate_->MemoryPressureIntervalInMS())) { 169 delegate_->MemoryPressureIntervalInMS())) {
152 WindowManager::GetInstance()->AddObserver(this); 170 WindowManager::GetInstance()->AddObserver(this);
153 WindowManager::GetInstance()->GetWindowListProvider()->AddObserver(this); 171 WindowManager::GetInstance()->GetWindowListProvider()->AddObserver(this);
154 ActivityManager::Get()->AddObserver(this); 172 ActivityManager::Get()->AddObserver(this);
155 } 173 }
156 174
157 ResourceManagerImpl::~ResourceManagerImpl() { 175 ResourceManagerImpl::~ResourceManagerImpl() {
158 ActivityManager::Get()->RemoveObserver(this); 176 ActivityManager::Get()->RemoveObserver(this);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 void ResourceManagerImpl::OnOverviewModeExit() { 216 void ResourceManagerImpl::OnOverviewModeExit() {
199 in_overview_mode_ = false; 217 in_overview_mode_ = false;
200 // Reorder the activities and manage the resources again since an order change 218 // Reorder the activities and manage the resources again since an order change
201 // might have caused a visibility change. 219 // might have caused a visibility change.
202 UpdateActivityOrder(); 220 UpdateActivityOrder();
203 ManageResource(); 221 ManageResource();
204 } 222 }
205 223
206 void ResourceManagerImpl::OnSplitViewModeEnter() { 224 void ResourceManagerImpl::OnSplitViewModeEnter() {
207 // Re-apply the memory pressure to make sure enough items are visible. 225 // Re-apply the memory pressure to make sure enough items are visible.
208 in_splitview_mode_ = true; 226 in_split_view_mode_ = true;
209 ManageResource(); 227 ManageResource();
210 } 228 }
211 229
212 230
213 void ResourceManagerImpl::OnSplitViewModeExit() { 231 void ResourceManagerImpl::OnSplitViewModeExit() {
214 // We don't do immediately something yet. The next ManageResource call will 232 // We don't do immediately something yet. The next ManageResource call will
215 // come soon. 233 // come soon.
216 in_splitview_mode_ = false; 234 in_split_view_mode_ = false;
217 } 235 }
218 236
219 void ResourceManagerImpl::OnWindowStackingChanged() { 237 void ResourceManagerImpl::OnWindowStackingChanged() {
220 activity_order_changed_ = true; 238 activity_order_changed_ = true;
221 if (pause_) { 239 if (pause_) {
222 queued_command_ = true; 240 queued_command_ = true;
223 return; 241 return;
224 } 242 }
225 243
226 // No need to do anything while being in overview mode. 244 // No need to do anything while being in overview mode.
227 if (in_overview_mode_) 245 if (in_overview_mode_)
228 return; 246 return;
229 247
230 // As long as we have to manage the list of activities ourselves, we need to 248 // As long as we have to manage the list of activities ourselves, we need to
231 // order it here. 249 // order it here.
232 UpdateActivityOrder(); 250 UpdateActivityOrder();
233 251
234 // Manage the resources of each activity. 252 // Manage the resources of each activity.
235 ManageResource(); 253 ManageResource();
236 } 254 }
237 255
238 void ResourceManagerImpl::OnWindowRemoved(aura::Window* removed_window, 256 void ResourceManagerImpl::OnWindowRemoved(aura::Window* removed_window,
239 int index) { 257 int index) {
240 } 258 }
241 259
242 void ResourceManagerImpl::OnMemoryPressure( 260 void ResourceManagerImpl::OnMemoryPressure(
243 MemoryPressureObserver::MemoryPressure pressure) { 261 MemoryPressureObserver::MemoryPressure pressure) {
262 if (pressure > current_memory_pressure_)
263 OnMemoryPressureIncreased();
244 current_memory_pressure_ = pressure; 264 current_memory_pressure_ = pressure;
245 ManageResource(); 265 ManageResource();
246 } 266 }
247 267
248 ResourceManagerDelegate* ResourceManagerImpl::GetDelegate() { 268 ResourceManagerDelegate* ResourceManagerImpl::GetDelegate() {
249 return delegate_.get(); 269 return delegate_.get();
250 } 270 }
251 271
252 void ResourceManagerImpl::ManageResource() { 272 void ResourceManagerImpl::ManageResource() {
253 // If there is none or only one app running we cannot do anything. 273 // If there is none or only one app running we cannot do anything.
254 if (activity_list_.size() <= 1U) 274 if (activity_list_.size() <= 1U)
255 return; 275 return;
256 276
257 if (pause_) { 277 if (pause_) {
258 queued_command_ = true; 278 queued_command_ = true;
259 return; 279 return;
260 } 280 }
261 281
262 // TODO(skuhne): This algorithm needs to take all kinds of predictive analysis 282 // Check that the visibility of items is properly set. Note that this might
263 // and running applications into account. For this first patch we only do a 283 // already trigger a release of resources. If this happens,
264 // very simple "floating window" algorithm which is surely not good enough. 284 // AllowedToUnloadActivity() will return false.
265 size_t max_running_activities = 5; 285 UpdateVisibilityStates();
266 switch (current_memory_pressure_) {
267 case MEMORY_PRESSURE_UNKNOWN:
268 // If we do not know how much memory we have we assume that it must be a
269 // high consumption.
270 // Fallthrough.
271 case MEMORY_PRESSURE_HIGH:
272 max_running_activities = 5;
273 break;
274 case MEMORY_PRESSURE_CRITICAL:
275 max_running_activities = 0;
276 break;
277 case MEMORY_PRESSURE_MODERATE:
278 max_running_activities = 7;
279 break;
280 case MEMORY_PRESSURE_LOW:
281 // This doesn't really matter. We do not change anything but turning
282 // activities visible.
283 max_running_activities = 10000;
284 break;
285 }
286 286
287 // Since resource deallocation takes time, we avoid to release more resources
288 // in short succession. Note that we come here periodically and if one call
289 // is not triggering an unload, the next one will.
290 if (AllowedToUnloadActivity())
291 TryToUnloadAnActivity();
292 }
293
294 void ResourceManagerImpl::UpdateVisibilityStates() {
287 // The first n activities should be treated as "visible", means they updated 295 // The first n activities should be treated as "visible", means they updated
288 // in overview mode and will keep their layer resources for faster switch 296 // in overview mode and will keep their layer resources for faster switch
289 // times. Usually we use |kMaxVisibleActivities| items, but when the memory 297 // times. Usually we use |kMaxVisibleActivities| items, but when the memory
290 // pressure gets critical we only hold as many as are really visible. 298 // pressure gets critical we only hold as many as are really visible.
291 size_t max_activities = kMaxVisibleActivities; 299 size_t max_activities = kMaxVisibleActivities;
292 if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL) 300 if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL)
293 max_activities = 1 + (in_splitview_mode_ ? 1 : 0); 301 max_activities = in_split_view_mode_ ? 2 : 1;
294 302
295 // Restart and / or bail if the order of activities changes due to our calls. 303 // Restart and / or bail if the order of activities changes due to our calls.
296 activity_order_changed_ = false; 304 activity_order_changed_ = false;
297 305
298 // Change the visibility of our activities in a pre-processing step. This is 306 // Change the visibility of our activities in a pre-processing step. This is
299 // required since it might change the order/number of activities. 307 // required since it might change the order/number of activities.
300 size_t index = 0; 308 size_t index = 0;
301 while (index < activity_list_.size()) { 309 while (index < activity_list_.size()) {
302 Activity* activity = activity_list_[index]; 310 Activity* activity = activity_list_[index];
303 Activity::ActivityState state = activity->GetCurrentState(); 311 Activity::ActivityState state = activity->GetCurrentState();
304 312
305 // The first |kMaxVisibleActivities| entries should be visible, all others 313 // The first |kMaxVisibleActivities| entries should be visible, all others
306 // invisible or at a lower activity state. 314 // invisible or at a lower activity state.
307 if (index < max_activities || 315 if (index < max_activities ||
308 (state == Activity::ACTIVITY_INVISIBLE || 316 (state == Activity::ACTIVITY_INVISIBLE ||
309 state == Activity::ACTIVITY_VISIBLE)) { 317 state == Activity::ACTIVITY_VISIBLE)) {
310 Activity::ActivityState visiblity_state = 318 Activity::ActivityState visiblity_state =
311 index < max_activities ? Activity::ACTIVITY_VISIBLE : 319 index < max_activities ? Activity::ACTIVITY_VISIBLE :
312 Activity::ACTIVITY_INVISIBLE; 320 Activity::ACTIVITY_INVISIBLE;
313 // Only change the state when it changes. Note that when the memory 321 // Only change the state when it changes. Note that when the memory
314 // pressure is critical, only the primary activities (1 or 2) are made 322 // pressure is critical, only the primary activities (1 or 2) are made
315 // visible. Furthermore, in relaxed mode we only want to turn visible, 323 // visible. Furthermore, in relaxed mode we only want to turn visible,
316 // never invisible. 324 // never invisible.
317 if (visiblity_state != state && 325 if (visiblity_state != state &&
318 (current_memory_pressure_ != MEMORY_PRESSURE_LOW || 326 (current_memory_pressure_ != MEMORY_PRESSURE_LOW ||
319 visiblity_state == Activity::ACTIVITY_VISIBLE)) { 327 visiblity_state == Activity::ACTIVITY_VISIBLE)) {
320 activity->SetCurrentState(visiblity_state); 328 activity->SetCurrentState(visiblity_state);
321 // If we turned an activity invisible, we should not at the same time 329 // If we turned an activity invisible, we are already releasing memory
322 // throw an activity out of memory. Thus we grant one more invisible 330 // and can hold off releasing more for now.
323 // Activity in that case.
324 if (visiblity_state == Activity::ACTIVITY_INVISIBLE) 331 if (visiblity_state == Activity::ACTIVITY_INVISIBLE)
325 max_running_activities++; 332 OnResourcesReleased();
326 } 333 }
327 } 334 }
328 335
329 // See which index we should handle next. 336 // See which index we should handle next.
330 if (activity_order_changed_) { 337 if (activity_order_changed_) {
331 activity_order_changed_ = false; 338 activity_order_changed_ = false;
332 index = 0; 339 index = 0;
333 } else { 340 } else {
334 ++index; 341 ++index;
335 } 342 }
336 } 343 }
344 }
337 345
338 // If there is only a low memory pressure, or our last call to release 346 void ResourceManagerImpl::TryToUnloadAnActivity() {
339 // resources cannot have had any impact yet, we return. 347 // TODO(skuhne): This algorithm needs to take all kinds of predictive analysis
340 // TODO(skuhne): The upper part of this function bumps up the state (to 348 // and running applications into account. For this first patch we only do a
341 // visible) and the lower part might unload one. Going forward this algorithm 349 // very simple "floating window" algorithm which is surely not good enough.
342 // will change significantly and when it does we might want to break this into 350 size_t max_running_activities = 5;
343 // two separate pieces. 351 switch (current_memory_pressure_) {
344 if (current_memory_pressure_ == MEMORY_PRESSURE_LOW || 352 case MEMORY_PRESSURE_UNKNOWN:
345 base::Time::Now() < next_resource_management_time_) 353 // If we do not know how much memory we have we assume that it must be a
346 return; 354 // high consumption.
347 // Do not release too many activities in short succession since it takes time 355 // Fallthrough.
348 // to release resources. As such wait the memory pressure interval before the 356 case MEMORY_PRESSURE_HIGH:
349 // next call. 357 max_running_activities = 5;
350 next_resource_management_time_ = base::Time::Now() + 358 break;
351 wait_time_for_resource_deallocation_; 359 case MEMORY_PRESSURE_CRITICAL:
360 max_running_activities = 0;
361 break;
362 case MEMORY_PRESSURE_MODERATE:
363 max_running_activities = 7;
364 break;
365 case MEMORY_PRESSURE_LOW:
366 NOTREACHED();
367 return;
368 }
352 369
353 // Check if/which activity we want to unload. 370 // Check if / which activity we want to unload.
354 Activity* oldest_media_activity = NULL; 371 Activity* oldest_media_activity = NULL;
355 std::vector<Activity*> unloadable_activities; 372 std::vector<Activity*> unloadable_activities;
356 for (std::vector<Activity*>::iterator it = activity_list_.begin(); 373 for (std::vector<Activity*>::iterator it = activity_list_.begin();
357 it != activity_list_.end(); ++it) { 374 it != activity_list_.end(); ++it) {
358 Activity::ActivityState state = (*it)->GetCurrentState(); 375 Activity::ActivityState state = (*it)->GetCurrentState();
359 // The activity should neither be unloaded nor visible. 376 // The activity should neither be unloaded nor visible.
360 if (state != Activity::ACTIVITY_UNLOADED && 377 if (state != Activity::ACTIVITY_UNLOADED &&
361 state != Activity::ACTIVITY_VISIBLE) { 378 state != Activity::ACTIVITY_VISIBLE) {
362 if ((*it)->GetMediaState() == Activity::ACTIVITY_MEDIA_STATE_NONE) { 379 if ((*it)->GetMediaState() == Activity::ACTIVITY_MEDIA_STATE_NONE) {
363 // Does not play media - so we can unload this immediately. 380 // Does not play media - so we can unload this immediately.
364 unloadable_activities.push_back(*it); 381 unloadable_activities.push_back(*it);
365 } else { 382 } else {
366 oldest_media_activity = *it; 383 oldest_media_activity = *it;
367 } 384 }
368 } 385 }
369 } 386 }
370 387
371 if (unloadable_activities.size() > max_running_activities) { 388 if (unloadable_activities.size() > max_running_activities) {
389 OnResourcesReleased();
372 unloadable_activities.back()->SetCurrentState(Activity::ACTIVITY_UNLOADED); 390 unloadable_activities.back()->SetCurrentState(Activity::ACTIVITY_UNLOADED);
373 return; 391 return;
374 } else if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL) { 392 } else if (current_memory_pressure_ == MEMORY_PRESSURE_CRITICAL) {
375 if (oldest_media_activity) { 393 if (oldest_media_activity) {
394 OnResourcesReleased();
376 oldest_media_activity->SetCurrentState(Activity::ACTIVITY_UNLOADED); 395 oldest_media_activity->SetCurrentState(Activity::ACTIVITY_UNLOADED);
377 LOG(WARNING) << "Unloading item to releave critical memory pressure"; 396 LOG(WARNING) << "Unloading item to releave critical memory pressure";
378 return; 397 return;
379 } 398 }
380 LOG(ERROR) << "[ResourceManager]: Single activity uses too much memory."; 399 LOG(ERROR) << "[ResourceManager]: Single activity uses too much memory.";
381 return; 400 return;
382 } 401 }
383 402
384 if (current_memory_pressure_ != MEMORY_PRESSURE_UNKNOWN) { 403 if (current_memory_pressure_ != MEMORY_PRESSURE_UNKNOWN) {
385 // Only show this warning when the memory pressure is actually known. This 404 // Only show this warning when the memory pressure is actually known. This
(...skipping 29 matching lines...) Expand all
415 } 434 }
416 } 435 }
417 // At this point the old list should be empty and we can swap the lists. 436 // At this point the old list should be empty and we can swap the lists.
418 DCHECK(!activity_list_.size()); 437 DCHECK(!activity_list_.size());
419 activity_list_ = new_activity_list; 438 activity_list_ = new_activity_list;
420 439
421 // Remember that the activity order has changed. 440 // Remember that the activity order has changed.
422 activity_order_changed_ = true; 441 activity_order_changed_ = true;
423 } 442 }
424 443
444 void ResourceManagerImpl::OnResourcesReleased() {
445 // Do not release too many activities in short succession since it takes time
446 // to release resources. As such wait the memory pressure interval before the
447 // next call.
448 next_resource_management_time_ = base::Time::Now() +
449 wait_time_for_resource_deallocation_;
450 }
451
452 void ResourceManagerImpl::OnMemoryPressureIncreased() {
453 // By setting the timer to Now, the next call will immediately be performed.
454 next_resource_management_time_ = base::Time::Now();
455 }
456
457 bool ResourceManagerImpl::AllowedToUnloadActivity() {
458 return current_memory_pressure_ != MEMORY_PRESSURE_LOW &&
459 base::Time::Now() >= next_resource_management_time_;
460 }
461
425 // static 462 // static
426 void ResourceManager::Create() { 463 void ResourceManager::Create() {
427 DCHECK(!instance); 464 DCHECK(!instance);
428 instance = new ResourceManagerImpl( 465 instance = new ResourceManagerImpl(
429 ResourceManagerDelegate::CreateResourceManagerDelegate()); 466 ResourceManagerDelegate::CreateResourceManagerDelegate());
430 } 467 }
431 468
432 // static 469 // static
433 ResourceManager* ResourceManager::Get() { 470 ResourceManager* ResourceManager::Get() {
434 return instance; 471 return instance;
435 } 472 }
436 473
437 // static 474 // static
438 void ResourceManager::Shutdown() { 475 void ResourceManager::Shutdown() {
439 DCHECK(instance); 476 DCHECK(instance);
440 delete instance; 477 delete instance;
441 instance = NULL; 478 instance = NULL;
442 } 479 }
443 480
444 ResourceManager::ResourceManager() {} 481 ResourceManager::ResourceManager() {}
445 482
446 ResourceManager::~ResourceManager() { 483 ResourceManager::~ResourceManager() {
447 DCHECK(instance); 484 DCHECK(instance);
448 instance = NULL; 485 instance = NULL;
449 } 486 }
450 487
451 } // namespace athena 488 } // namespace athena
OLDNEW
« no previous file with comments | « athena/resource_manager/memory_pressure_notifier.h ('k') | athena/resource_manager/resource_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698