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

Side by Side Diff: base/memory/discardable_memory_emulated.cc

Issue 204733003: base: Refactor DiscardableMemoryManager for use with different type of allocations. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add missing unlock call and remove unnecessary unlock call Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "base/memory/discardable_memory_emulated.h" 5 #include "base/memory/discardable_memory_emulated.h"
6 6
7 #include "base/bind.h"
7 #include "base/lazy_instance.h" 8 #include "base/lazy_instance.h"
8 #include "base/memory/discardable_memory_manager.h" 9 #include "base/memory/memory_pressure_listener.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/threading/thread_checker.h"
9 12
10 namespace base { 13 namespace base {
11 14
12 namespace { 15 namespace {
13 16
14 base::LazyInstance<internal::DiscardableMemoryManager>::Leaky g_manager = 17 class DiscardableMemoryAllocationImpl
willchan no longer on Chromium 2014/04/01 01:11:08 Maybe we should name this DiscardableMemoryHeapAll
reveman 2014/04/03 17:02:12 I added a comment here to emphasize the use of hea
willchan no longer on Chromium 2014/04/15 20:51:31 I will defer to you here. Please take my comment a
18 : public internal::DiscardableMemoryAllocation {
19 public:
20 explicit DiscardableMemoryAllocationImpl(size_t bytes)
21 : memory_(new uint8[bytes]) {}
22
23 // Overridden from internal::DiscardableMemoryAllocation:
24 virtual bool Lock() OVERRIDE { return true; }
25 virtual void Unlock() OVERRIDE {}
26 virtual void* Memory() OVERRIDE { return memory_.get(); }
27
28 private:
29 scoped_ptr<uint8[]> memory_;
30 };
31
32 // This is admittedly pretty magical. It's approximately enough memory for four
33 // 2560x1600 images.
34 const size_t kDefaultDiscardableMemoryLimit = 64 * 1024 * 1024;
35
36 // Under moderate memory pressure, we will purge until usage is within this
37 // limit.
38 const size_t kBytesToKeepUnderModeratePressure =
39 kDefaultDiscardableMemoryLimit / 4;
40
41 class DiscardableMemoryManagerImpl
42 : public internal::DiscardableMemoryManager,
43 public internal::DiscardableMemoryAllocation::Factory {
44 public:
45 DiscardableMemoryManagerImpl()
46 : internal::DiscardableMemoryManager(this,
Philippe 2014/03/20 18:08:31 I think this part is slightly hairy :) Correct me
reveman 2014/03/20 19:08:22 Correct.
Philippe 2014/03/21 09:13:09 I think we will have to initialize the factory bef
Philippe 2014/03/21 09:49:19 I think this should be a reasonable compromise tha
reveman 2014/03/21 12:32:16 Why not?
reveman 2014/03/21 12:32:16 I don't like that either. Awkward for the manager
Philippe 2014/03/21 12:40:50 Because this would be a direct violation of the Li
reveman 2014/03/22 16:49:34 Correct, DiscardableMemoryManagerImpl is not a Fac
Philippe 2014/03/24 09:35:31 Just to be clear and so that the information is pr
willchan no longer on Chromium 2014/04/01 01:11:08 I am not fully up to date with Philippe's proposal
reveman 2014/04/03 17:02:12 Do we really need to avoid all kinds of concrete c
Philippe 2014/04/14 15:35:47 I agree, let's move this forward :) I think I have
willchan no longer on Chromium 2014/04/15 20:51:31 It's not strictly disallowed, but it's strongly di
47 kDefaultDiscardableMemoryLimit) {}
48
49 // Overridden from internal::DiscardableMemoryAllocation::Factory:
50 virtual scoped_ptr<internal::DiscardableMemoryAllocation>
51 CreateLockedAllocation(size_t bytes) OVERRIDE {
52 return make_scoped_ptr<internal::DiscardableMemoryAllocation>(
53 new DiscardableMemoryAllocationImpl(bytes));
54 }
55
56 void RegisterMemoryPressureListener() {
57 DCHECK(thread_checker_.CalledOnValidThread());
58 DCHECK(base::MessageLoop::current());
59 DCHECK(!memory_pressure_listener_);
60 memory_pressure_listener_.reset(new MemoryPressureListener(base::Bind(
61 &DiscardableMemoryManagerImpl::OnMemoryPressure, Unretained(this))));
62 }
63
64 void UnregisterMemoryPressureListener() {
65 DCHECK(thread_checker_.CalledOnValidThread());
66 DCHECK(memory_pressure_listener_);
67 memory_pressure_listener_.reset();
68 }
69
70 // This can be called as a hint that the system is under memory pressure.
71 void OnMemoryPressure(
72 MemoryPressureListener::MemoryPressureLevel pressure_level) {
73 switch (pressure_level) {
74 case MemoryPressureListener::MEMORY_PRESSURE_MODERATE:
75 PurgeUntilUsageIsWithin(kBytesToKeepUnderModeratePressure);
76 return;
77 case MemoryPressureListener::MEMORY_PRESSURE_CRITICAL:
78 PurgeUntilUsageIsWithin(0u);
79 return;
80 }
81
82 NOTREACHED();
83 }
84
85 private:
86 // Allows us to be respond when the system reports that it is under memory
87 // pressure.
88 scoped_ptr<MemoryPressureListener> memory_pressure_listener_;
89
90 base::ThreadChecker thread_checker_;
91 };
92 base::LazyInstance<DiscardableMemoryManagerImpl>::Leaky g_manager =
15 LAZY_INSTANCE_INITIALIZER; 93 LAZY_INSTANCE_INITIALIZER;
16 94
17 } // namespace 95 } // namespace
18 96
19 namespace internal { 97 namespace internal {
20 98
21 DiscardableMemoryEmulated::DiscardableMemoryEmulated(size_t size) 99 DiscardableMemoryEmulated::DiscardableMemoryEmulated(size_t size)
22 : is_locked_(false) { 100 : allocation_id_(g_manager.Pointer()->Register(size)), memory_(NULL) {}
23 g_manager.Pointer()->Register(this, size);
24 }
25 101
26 DiscardableMemoryEmulated::~DiscardableMemoryEmulated() { 102 DiscardableMemoryEmulated::~DiscardableMemoryEmulated() {
27 if (is_locked_) 103 g_manager.Pointer()->Unregister(allocation_id_);
28 Unlock();
29 g_manager.Pointer()->Unregister(this);
30 } 104 }
31 105
32 // static 106 // static
33 void DiscardableMemoryEmulated::RegisterMemoryPressureListeners() { 107 void DiscardableMemoryEmulated::RegisterMemoryPressureListeners() {
34 g_manager.Pointer()->RegisterMemoryPressureListener(); 108 g_manager.Pointer()->RegisterMemoryPressureListener();
35 } 109 }
36 110
37 // static 111 // static
38 void DiscardableMemoryEmulated::UnregisterMemoryPressureListeners() { 112 void DiscardableMemoryEmulated::UnregisterMemoryPressureListeners() {
39 g_manager.Pointer()->UnregisterMemoryPressureListener(); 113 g_manager.Pointer()->UnregisterMemoryPressureListener();
40 } 114 }
41 115
42 // static 116 // static
43 void DiscardableMemoryEmulated::PurgeForTesting() { 117 void DiscardableMemoryEmulated::PurgeForTesting() {
44 g_manager.Pointer()->PurgeAll(); 118 g_manager.Pointer()->PurgeUntilUsageIsWithin(0u);
45 } 119 }
46 120
47 bool DiscardableMemoryEmulated::Initialize() { 121 bool DiscardableMemoryEmulated::Initialize() {
48 return Lock() == DISCARDABLE_MEMORY_LOCK_STATUS_PURGED; 122 return Lock() == DISCARDABLE_MEMORY_LOCK_STATUS_PURGED;
49 } 123 }
50 124
51 DiscardableMemoryLockStatus DiscardableMemoryEmulated::Lock() { 125 DiscardableMemoryLockStatus DiscardableMemoryEmulated::Lock() {
52 DCHECK(!is_locked_); 126 DCHECK(!memory_);
53 127
54 bool purged = false; 128 bool purged = false;
55 memory_ = g_manager.Pointer()->Acquire(this, &purged); 129 memory_ = g_manager.Pointer()->Lock(allocation_id_, &purged);
56 if (!memory_) 130 if (!memory_)
57 return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED; 131 return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
58 132
59 is_locked_ = true;
60 return purged ? DISCARDABLE_MEMORY_LOCK_STATUS_PURGED 133 return purged ? DISCARDABLE_MEMORY_LOCK_STATUS_PURGED
61 : DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS; 134 : DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS;
62 } 135 }
63 136
64 void DiscardableMemoryEmulated::Unlock() { 137 void DiscardableMemoryEmulated::Unlock() {
65 DCHECK(is_locked_); 138 DCHECK(memory_);
66 g_manager.Pointer()->Release(this, memory_.Pass()); 139 g_manager.Pointer()->Unlock(allocation_id_);
67 is_locked_ = false; 140 memory_ = NULL;
68 } 141 }
69 142
70 void* DiscardableMemoryEmulated::Memory() const { 143 void* DiscardableMemoryEmulated::Memory() const {
71 DCHECK(memory_); 144 DCHECK(memory_);
72 return memory_.get(); 145 return memory_;
73 } 146 }
74 147
75 } // namespace internal 148 } // namespace internal
76 } // namespace base 149 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698