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

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

Issue 17106004: Add discardable memory emulation for non-android/mac platforms (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 6 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
(Empty)
1 // Copyright (c) 2013 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 "base/memory/discardable_memory_provider.h"
6
7 #include "base/memory/discardable_memory.h"
8 #include "base/message_loop.h"
9 #include "base/run_loop.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace base {
13
14 class DiscardableMemoryProviderTest : public testing::Test {
15 public:
16 DiscardableMemoryProviderTest()
17 : message_loop_(MessageLoop::TYPE_IO),
18 provider_(new DiscardableMemoryProvider) {
19 DiscardableMemoryProvider::SetInstanceForTest(provider_.get());
Avi (use Gerrit) 2013/06/18 00:00:46 I'm lost; why are we keeping our own provider here
20 }
21
22 virtual ~DiscardableMemoryProviderTest() {
23 DiscardableMemoryProvider::SetInstanceForTest(NULL);
24 }
25
26 protected:
27 void Register(DiscardableMemory* discardable) {
28 DiscardableMemoryProvider::GetInstance()->Register(discardable);
29 }
30
31 const DiscardableMemoryProvider::AllocationMap& allocations() const {
32 return DiscardableMemoryProvider::GetInstance()->allocations_;
33 }
34
35 size_t bytes_allocated() const {
36 return DiscardableMemoryProvider::GetInstance()->bytes_allocated_;
37 }
38
39 void* Memory(const DiscardableMemory& discardable) const {
40 return discardable.memory_;
41 }
42
43 void SetDiscardableMemoryLimit(size_t bytes) {
44 DiscardableMemoryProvider::GetInstance()->
45 SetDiscardableMemoryLimit(bytes);
46 }
47
48 void SetBytesToReclaimUnderModeratePressure(size_t bytes) {
49 DiscardableMemoryProvider::GetInstance()->
50 SetBytesToReclaimUnderModeratePressure(bytes);
51 }
52
53 private:
54 MessageLoop message_loop_;
55 scoped_ptr<DiscardableMemoryProvider> provider_;
56 };
57
58 TEST_F(DiscardableMemoryProviderTest, Register) {
59 DiscardableMemory discardable;
60 Register(&discardable);
61 ASSERT_NE(allocations().end(), allocations().Peek(&discardable));
62 ASSERT_EQ(0u, bytes_allocated());
63 }
64
65 TEST_F(DiscardableMemoryProviderTest, InitializeAndLock) {
66 DiscardableMemory discardable;
67 ASSERT_EQ(static_cast<void*>(NULL), Memory(discardable));
68 size_t size = 1024;
69 ASSERT_TRUE(discardable.InitializeAndLock(size));
70 ASSERT_NE(allocations().end(), allocations().Peek(&discardable));
71 ASSERT_NE(static_cast<void*>(NULL), Memory(discardable));
72 ASSERT_EQ(1024u, bytes_allocated());
73 ASSERT_TRUE(discardable.is_locked());
74 }
75
76 TEST_F(DiscardableMemoryProviderTest, InitializeAndLockZeroSize) {
77 DiscardableMemory discardable;
78 ASSERT_EQ(static_cast<void*>(NULL), Memory(discardable));
79 size_t size = 0;
80 ASSERT_FALSE(discardable.InitializeAndLock(size));
81 ASSERT_NE(allocations().end(), allocations().Peek(&discardable));
82 ASSERT_EQ(static_cast<void*>(NULL), Memory(discardable));
83 ASSERT_EQ(0u, bytes_allocated());
84 ASSERT_FALSE(discardable.is_locked());
85 }
86
87 TEST_F(DiscardableMemoryProviderTest, LockBeforeInitialization) {
88 DiscardableMemory discardable;
89 ASSERT_EQ(DISCARDABLE_MEMORY_FAILED, discardable.Lock());
90 }
91
92 TEST_F(DiscardableMemoryProviderTest, LockAfterUnlock) {
93 DiscardableMemory discardable;
94 ASSERT_EQ(static_cast<void*>(NULL), Memory(discardable));
95 size_t size = 1024;
96 ASSERT_TRUE(discardable.InitializeAndLock(size));
97 ASSERT_NE(allocations().end(), allocations().Peek(&discardable));
98 ASSERT_NE(static_cast<void*>(NULL), Memory(discardable));
99 ASSERT_EQ(1024u, bytes_allocated());
100 ASSERT_TRUE(discardable.is_locked());
101
102 // Now to unlock so we can lock later.
103 discardable.Unlock();
104 ASSERT_FALSE(discardable.is_locked());
105
106 ASSERT_EQ(DISCARDABLE_MEMORY_SUCCESS, discardable.Lock());
107 ASSERT_TRUE(discardable.is_locked());
108 }
109
110 TEST_F(DiscardableMemoryProviderTest, LockAfterPurge) {
111 DiscardableMemory discardable;
112 ASSERT_EQ(static_cast<void*>(NULL), Memory(discardable));
113 size_t size = 1024;
114 ASSERT_TRUE(discardable.InitializeAndLock(size));
115 ASSERT_NE(allocations().end(), allocations().Peek(&discardable));
116 ASSERT_NE(static_cast<void*>(NULL), Memory(discardable));
117 ASSERT_EQ(1024u, bytes_allocated());
118 ASSERT_TRUE(discardable.is_locked());
119
120 // Now to unlock so we can lock later.
121 discardable.Unlock();
122 ASSERT_FALSE(discardable.is_locked());
123
124 // Force the system to purge.
125 MemoryPressureListener::NotifyMemoryPressure(
126 MemoryPressureListener::MEMORY_PRESSURE_CRITICAL);
127
128 // Required because ObserverListThreadSafe notifies via PostTask.
129 RunLoop().RunUntilIdle();
130
131 ASSERT_EQ(DISCARDABLE_MEMORY_PURGED, discardable.Lock());
132 ASSERT_TRUE(discardable.is_locked());
133 }
134
135 TEST_F(DiscardableMemoryProviderTest, LockAfterPurgeAndCannotReallocate) {
136 DiscardableMemory discardable;
137 ASSERT_EQ(static_cast<void*>(NULL), Memory(discardable));
138 size_t size = 1024;
139 ASSERT_TRUE(discardable.InitializeAndLock(size));
140 ASSERT_NE(allocations().end(), allocations().Peek(&discardable));
141 ASSERT_NE(static_cast<void*>(NULL), Memory(discardable));
142 ASSERT_EQ(1024u, bytes_allocated());
143 ASSERT_TRUE(discardable.is_locked());
144
145 // Now to unlock so we can lock later.
146 discardable.Unlock();
147 ASSERT_FALSE(discardable.is_locked());
148
149 // Force the system to purge.
150 MemoryPressureListener::NotifyMemoryPressure(
151 MemoryPressureListener::MEMORY_PRESSURE_CRITICAL);
152
153 // Required because ObserverListThreadSafe notifies via PostTask.
154 RunLoop().RunUntilIdle();
155
156 // Set max allowed allocation to 1 byte. This will make reallocation fail.
157 SetDiscardableMemoryLimit(1);
158
159 ASSERT_EQ(DISCARDABLE_MEMORY_FAILED, discardable.Lock());
160 ASSERT_FALSE(discardable.is_locked());
161 }
162
163 #define DiscardableMemoryProviderPermutionTest(name, d0, d1, d2, pressure) \
164 TEST_F(DiscardableMemoryProviderTest, name##_##d0##_##d1##_##d2) { \
165 DiscardableMemory discardables[3]; \
166 for (int i = 0; i < 3; ++i) { \
167 ASSERT_EQ(static_cast<void*>(NULL), Memory(discardables[i])); \
168 ASSERT_TRUE(discardables[i].InitializeAndLock(1024)); \
169 discardables[i].Unlock(); \
170 ASSERT_NE(static_cast<void*>(NULL), Memory(discardables[i])); \
171 } \
172 int ordering[] = { d0, d1, d2 }; \
173 for (int i = 0; i < 3; ++i) { \
174 int current_index = ordering[i]; \
175 ASSERT_NE(DISCARDABLE_MEMORY_FAILED, discardables[current_index].Lock()); \
176 if (i > 0) \
177 discardables[current_index].Unlock(); \
178 } \
179 SetBytesToReclaimUnderModeratePressure(1024); \
180 if (pressure) { \
181 MemoryPressureListener::NotifyMemoryPressure( \
182 MemoryPressureListener::MEMORY_PRESSURE_MODERATE); \
183 RunLoop().RunUntilIdle(); \
184 } else { \
185 SetDiscardableMemoryLimit(2048); \
186 } \
187 for (int i = 0; i < 3; ++i) { \
188 if (i == 1) \
189 ASSERT_EQ(static_cast<void*>(NULL), Memory(discardables[ordering[i]])); \
190 else \
191 ASSERT_NE(static_cast<void*>(NULL), Memory(discardables[ordering[i]])); \
192 } \
193 }
194
195 #define DiscardableMemoryProviderPermutions(name, pressure) \
196 DiscardableMemoryProviderPermutionTest(name, 0, 1, 2, pressure); \
197 DiscardableMemoryProviderPermutionTest(name, 0, 2, 1, pressure); \
198 DiscardableMemoryProviderPermutionTest(name, 1, 0, 2, pressure); \
199 DiscardableMemoryProviderPermutionTest(name, 1, 2, 0, pressure); \
200 DiscardableMemoryProviderPermutionTest(name, 2, 0, 1, pressure); \
201 DiscardableMemoryProviderPermutionTest(name, 2, 1, 0, pressure);
202
203 DiscardableMemoryProviderPermutions(LRUDiscardedModeratePressure, true);
204 DiscardableMemoryProviderPermutions(LRUDiscardedExceedLimit, false);
205
206 TEST_F(DiscardableMemoryProviderTest, CriticalPressureFreesAllUnlocked) {
207 DiscardableMemory discardables[3];
208 for (int i = 0; i < 3; ++i) {
209 ASSERT_EQ(static_cast<void*>(NULL), Memory(discardables[i]));
210 ASSERT_TRUE(discardables[i].InitializeAndLock(1024));
211 discardables[i].Unlock();
212 ASSERT_NE(static_cast<void*>(NULL), Memory(discardables[i]));
213 }
214
215 for (int i = 0; i < 3; ++i) {
216 ASSERT_NE(DISCARDABLE_MEMORY_FAILED, discardables[i].Lock());
217 if (i > 0)
218 discardables[i].Unlock();
219 }
220
221 MemoryPressureListener::NotifyMemoryPressure(
222 MemoryPressureListener::MEMORY_PRESSURE_CRITICAL);
223 RunLoop().RunUntilIdle();
224
225 for (int i = 0; i < 3; ++i) {
226 if (discardables[i].is_locked())
227 ASSERT_NE(static_cast<void*>(NULL), Memory(discardables[i]));
228 else
229 ASSERT_EQ(static_cast<void*>(NULL), Memory(discardables[i]));
230 }
231 }
232
233 TEST_F(DiscardableMemoryProviderTest, NormalDestruction) {
234 {
235 DiscardableMemory discardable;
236 size_t size = 1024;
237 ASSERT_TRUE(discardable.InitializeAndLock(size));
238 ASSERT_NE(allocations().end(), allocations().Peek(&discardable));
239 ASSERT_EQ(1024u, bytes_allocated());
240 }
241 ASSERT_TRUE(allocations().empty());
242 ASSERT_EQ(0u, bytes_allocated());
243 }
244
245 TEST_F(DiscardableMemoryProviderTest, DestructionWhileLocked) {
246 {
247 DiscardableMemory discardable;
248 ASSERT_EQ(static_cast<void*>(NULL), Memory(discardable));
249 size_t size = 1024;
250 ASSERT_TRUE(discardable.InitializeAndLock(size));
251 ASSERT_NE(allocations().end(), allocations().Peek(&discardable));
252 ASSERT_NE(static_cast<void*>(NULL), Memory(discardable));
253 ASSERT_EQ(1024u, bytes_allocated());
254 ASSERT_TRUE(discardable.is_locked());
255 }
256 // Should have ignored the "locked" status and freed the discardable memory.
257 ASSERT_TRUE(allocations().empty());
258 ASSERT_EQ(0u, bytes_allocated());
259 }
260
261 TEST_F(DiscardableMemoryProviderTest, MemoryBeforeLock) {
262 DiscardableMemory discardable;
263 // We *must* die if we are asked to vend a pointer to unlocked memory.
264 EXPECT_DEATH(discardable.Memory(), ".*Check failed.*");
265 }
266
267 TEST_F(DiscardableMemoryProviderTest, MemoryAfterUnlock) {
268 DiscardableMemory discardable;
269 ASSERT_EQ(static_cast<void*>(NULL), Memory(discardable));
270 size_t size = 1024;
271 ASSERT_TRUE(discardable.InitializeAndLock(size));
272 ASSERT_NE(allocations().end(), allocations().Peek(&discardable));
273 ASSERT_NE(static_cast<void*>(NULL), Memory(discardable));
274 ASSERT_EQ(1024u, bytes_allocated());
275 ASSERT_TRUE(discardable.is_locked());
276 discardable.Unlock();
277 ASSERT_FALSE(discardable.is_locked());
278 // We *must* die if we are asked to vend a pointer to unlocked memory.
279 EXPECT_DEATH(discardable.Memory(), ".*Check failed.*");
280 }
281
282 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698