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

Side by Side Diff: base/memory/discardable_memory_manager_unittest.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_manager.h" 5 #include "base/memory/discardable_memory_manager.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/memory/discardable_memory.h"
9 #include "base/run_loop.h"
10 #include "base/synchronization/waitable_event.h" 8 #include "base/synchronization/waitable_event.h"
11 #include "base/threading/thread.h" 9 #include "base/threading/thread.h"
12 #include "testing/gtest/include/gtest/gtest.h" 10 #include "testing/gtest/include/gtest/gtest.h"
13 11
14 namespace base { 12 namespace base {
15 13
16 class DiscardableMemoryManagerTestBase { 14 class DiscardableMemoryAllocationImpl
15 : public internal::DiscardableMemoryAllocation {
17 public: 16 public:
18 class TestDiscardableMemory : public DiscardableMemory { 17 // Overridden from internal::DiscardableMemoryAllocation:
19 public: 18 virtual bool Lock() OVERRIDE { return true; }
20 TestDiscardableMemory( 19 virtual void Unlock() OVERRIDE {}
21 internal::DiscardableMemoryManager* manager, size_t size) 20 virtual void* Memory() OVERRIDE {
22 : manager_(manager), 21 return reinterpret_cast<void*>(0xdeadbeef);
23 is_locked_(false) { 22 }
24 manager_->Register(this, size); 23 };
25 }
26 24
27 virtual ~TestDiscardableMemory() { 25 const size_t kDefaultDiscardableMemoryLimit = 8192u;
28 if (is_locked_)
29 Unlock();
30 manager_->Unregister(this);
31 }
32 26
33 // Overridden from DiscardableMemory: 27 class DiscardableMemoryManagerTestBase
34 virtual DiscardableMemoryLockStatus Lock() OVERRIDE { 28 : public internal::DiscardableMemoryAllocation::Factory {
35 DCHECK(!is_locked_); 29 public:
30 struct Allocation {
31 Allocation(internal::DiscardableMemoryManager* manager, size_t bytes)
32 : manager(manager), id(manager->Register(bytes)) {}
33 ~Allocation() { manager->Unregister(id); }
36 34
37 bool purged = false; 35 internal::DiscardableMemoryManager* manager;
38 memory_ = manager_->Acquire(this, &purged); 36 internal::DiscardableMemoryManager::AllocationId id;
39 if (!memory_)
40 return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED;
41
42 is_locked_ = true;
43 return purged ? DISCARDABLE_MEMORY_LOCK_STATUS_PURGED
44 : DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS;
45 }
46 virtual void Unlock() OVERRIDE {
47 DCHECK(is_locked_);
48 manager_->Release(this, memory_.Pass());
49 is_locked_ = false;
50 }
51 virtual void* Memory() const OVERRIDE {
52 DCHECK(memory_);
53 return memory_.get();
54 }
55
56 private:
57 internal::DiscardableMemoryManager* manager_;
58 scoped_ptr<uint8, FreeDeleter> memory_;
59 bool is_locked_;
60
61 DISALLOW_COPY_AND_ASSIGN(TestDiscardableMemory);
62 }; 37 };
63 38
64 DiscardableMemoryManagerTestBase() 39 DiscardableMemoryManagerTestBase()
65 : manager_(new internal::DiscardableMemoryManager) { 40 : manager_(new internal::DiscardableMemoryManager(
66 manager_->RegisterMemoryPressureListener(); 41 this,
42 kDefaultDiscardableMemoryLimit)) {}
43
44 // Overridden from internal::DiscardableMemoryAllocation::Factory:
45 virtual scoped_ptr<internal::DiscardableMemoryAllocation>
46 CreateLockedAllocation(size_t bytes) OVERRIDE {
47 return make_scoped_ptr<internal::DiscardableMemoryAllocation>(
48 new DiscardableMemoryAllocationImpl);
67 } 49 }
68 50
69 protected: 51 protected:
70 bool IsRegistered(const DiscardableMemory* discardable) { 52 bool IsRegistered(Allocation* allocation) {
71 return manager_->IsRegisteredForTest(discardable); 53 return manager_->IsRegisteredForTest(allocation->id);
72 } 54 }
73 55
74 bool CanBePurged(const DiscardableMemory* discardable) { 56 bool CanBePurged(Allocation* allocation) {
75 return manager_->CanBePurgedForTest(discardable); 57 return manager_->CanBePurgedForTest(allocation->id);
76 } 58 }
77 59
78 size_t BytesAllocated() const { 60 size_t BytesAllocated() const {
79 return manager_->GetBytesAllocatedForTest(); 61 return manager_->GetBytesAllocatedForTest();
80 } 62 }
81 63
82 void* Memory(const DiscardableMemory* discardable) const { 64 bool Lock(Allocation* allocation) {
83 return discardable->Memory(); 65 bool purged;
66 return !!manager_->Lock(allocation->id, &purged);
84 } 67 }
85 68
69 bool Lock(Allocation* allocation, bool expected_to_be_purged) {
70 bool purged;
71 return !!manager_->Lock(allocation->id, &purged) &&
72 expected_to_be_purged == purged;
73 }
74
75 void Unlock(Allocation* allocation) { manager_->Unlock(allocation->id); }
76
86 void SetDiscardableMemoryLimit(size_t bytes) { 77 void SetDiscardableMemoryLimit(size_t bytes) {
87 manager_->SetDiscardableMemoryLimit(bytes); 78 manager_->SetDiscardableMemoryLimit(bytes);
88 } 79 }
89 80
90 void SetBytesToKeepUnderModeratePressure(size_t bytes) { 81 scoped_ptr<Allocation> Create(size_t bytes) {
91 manager_->SetBytesToKeepUnderModeratePressure(bytes); 82 return make_scoped_ptr(new Allocation(manager_.get(), bytes));
92 } 83 }
93 84
94 scoped_ptr<DiscardableMemory> CreateLockedMemory(size_t size) { 85 scoped_ptr<Allocation> CreateLocked(size_t bytes) {
95 scoped_ptr<TestDiscardableMemory> memory( 86 scoped_ptr<Allocation> allocation(Create(bytes));
96 new TestDiscardableMemory(manager_.get(), size)); 87 EXPECT_TRUE(IsRegistered(allocation.get()));
97 if (memory->Lock() != DISCARDABLE_MEMORY_LOCK_STATUS_PURGED) 88 EXPECT_TRUE(Lock(allocation.get(), true));
98 return scoped_ptr<DiscardableMemory>(); 89 return allocation.Pass();
99 return memory.PassAs<DiscardableMemory>(); 90 }
91
92 void PurgeUntilUsageIsWithin(size_t limit) {
93 manager_->PurgeUntilUsageIsWithin(limit);
100 } 94 }
101 95
102 private: 96 private:
103 MessageLoopForIO message_loop_;
104 scoped_ptr<internal::DiscardableMemoryManager> manager_; 97 scoped_ptr<internal::DiscardableMemoryManager> manager_;
105 }; 98 };
106 99
107 class DiscardableMemoryManagerTest 100 class DiscardableMemoryManagerTest
108 : public DiscardableMemoryManagerTestBase, 101 : public DiscardableMemoryManagerTestBase,
109 public testing::Test { 102 public testing::Test {
110 public: 103 public:
111 DiscardableMemoryManagerTest() {} 104 DiscardableMemoryManagerTest() {}
112 }; 105 };
113 106
114 TEST_F(DiscardableMemoryManagerTest, CreateLockedMemory) { 107 TEST_F(DiscardableMemoryManagerTest, CreateAndLock) {
115 size_t size = 1024; 108 size_t size = 1024u;
116 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); 109 const scoped_ptr<Allocation> allocation(Create(size));
117 EXPECT_TRUE(IsRegistered(discardable.get())); 110 EXPECT_TRUE(IsRegistered(allocation.get()));
118 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get())); 111 EXPECT_TRUE(Lock(allocation.get(), true));
119 EXPECT_EQ(1024u, BytesAllocated()); 112 EXPECT_EQ(1024u, BytesAllocated());
120 EXPECT_FALSE(CanBePurged(discardable.get())); 113 EXPECT_FALSE(CanBePurged(allocation.get()));
121 } 114 }
122 115
123 TEST_F(DiscardableMemoryManagerTest, CreateLockedMemoryZeroSize) { 116 TEST_F(DiscardableMemoryManagerTest, CreateZeroSize) {
124 size_t size = 0; 117 size_t size = 0u;
125 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); 118 const scoped_ptr<Allocation> allocation(Create(size));
126 EXPECT_FALSE(discardable); 119 EXPECT_TRUE(IsRegistered(allocation.get()));
127 EXPECT_FALSE(IsRegistered(discardable.get())); 120 EXPECT_FALSE(Lock(allocation.get(), true));
128 EXPECT_EQ(0u, BytesAllocated()); 121 EXPECT_EQ(0u, BytesAllocated());
129 } 122 }
130 123
131 TEST_F(DiscardableMemoryManagerTest, LockAfterUnlock) { 124 TEST_F(DiscardableMemoryManagerTest, LockAfterUnlock) {
132 size_t size = 1024; 125 size_t size = 1024u;
133 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); 126 const scoped_ptr<Allocation> allocation(CreateLocked(size));
134 EXPECT_TRUE(IsRegistered(discardable.get()));
135 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
136 EXPECT_EQ(1024u, BytesAllocated()); 127 EXPECT_EQ(1024u, BytesAllocated());
137 EXPECT_FALSE(CanBePurged(discardable.get())); 128 EXPECT_FALSE(CanBePurged(allocation.get()));
138 129
139 // Now unlock so we can lock later. 130 // Now unlock so we can lock later.
140 discardable->Unlock(); 131 Unlock(allocation.get());
141 EXPECT_TRUE(CanBePurged(discardable.get())); 132 EXPECT_TRUE(CanBePurged(allocation.get()));
142 133
143 EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS, discardable->Lock()); 134 EXPECT_TRUE(Lock(allocation.get(), false));
144 EXPECT_FALSE(CanBePurged(discardable.get())); 135 EXPECT_FALSE(CanBePurged(allocation.get()));
145 } 136 }
146 137
147 TEST_F(DiscardableMemoryManagerTest, LockAfterPurge) { 138 TEST_F(DiscardableMemoryManagerTest, LockAfterPurge) {
148 size_t size = 1024; 139 size_t size = 1024u;
149 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); 140 const scoped_ptr<Allocation> allocation(CreateLocked(size));
150 EXPECT_TRUE(IsRegistered(discardable.get()));
151 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
152 EXPECT_EQ(1024u, BytesAllocated()); 141 EXPECT_EQ(1024u, BytesAllocated());
153 EXPECT_FALSE(CanBePurged(discardable.get())); 142 EXPECT_FALSE(CanBePurged(allocation.get()));
154 143
155 // Now unlock so we can lock later. 144 // Now unlock so we can lock later.
156 discardable->Unlock(); 145 Unlock(allocation.get());
157 EXPECT_TRUE(CanBePurged(discardable.get())); 146 EXPECT_TRUE(CanBePurged(allocation.get()));
158 147
159 // Force the system to purge. 148 // Force the system to purge.
160 MemoryPressureListener::NotifyMemoryPressure( 149 PurgeUntilUsageIsWithin(0u);
161 MemoryPressureListener::MEMORY_PRESSURE_CRITICAL);
162 150
163 // Required because ObserverListThreadSafe notifies via PostTask. 151 EXPECT_TRUE(Lock(allocation.get(), true));
164 RunLoop().RunUntilIdle(); 152 EXPECT_FALSE(CanBePurged(allocation.get()));
165
166 EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_PURGED, discardable->Lock());
167 EXPECT_FALSE(CanBePurged(discardable.get()));
168 } 153 }
169 154
170 TEST_F(DiscardableMemoryManagerTest, LockAfterPurgeAndCannotReallocate) { 155 TEST_F(DiscardableMemoryManagerTest, LockAfterPurgeAndCannotReallocate) {
171 size_t size = 1024; 156 size_t size = 1024u;
172 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); 157 const scoped_ptr<Allocation> allocation(CreateLocked(size));
173 EXPECT_TRUE(IsRegistered(discardable.get()));
174 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
175 EXPECT_EQ(1024u, BytesAllocated()); 158 EXPECT_EQ(1024u, BytesAllocated());
176 EXPECT_FALSE(CanBePurged(discardable.get())); 159 EXPECT_FALSE(CanBePurged(allocation.get()));
177 160
178 // Now unlock so we can lock later. 161 // Now unlock so we can lock later.
179 discardable->Unlock(); 162 Unlock(allocation.get());
180 EXPECT_TRUE(CanBePurged(discardable.get())); 163 EXPECT_TRUE(CanBePurged(allocation.get()));
181 164
182 // Set max allowed allocation to 1 byte. This will make cause the memory 165 // Set max allowed allocation to 1 byte. This will cause the memory to be
183 // to be purged. 166 // purged.
184 SetDiscardableMemoryLimit(1); 167 SetDiscardableMemoryLimit(1);
185 168
186 EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_PURGED, discardable->Lock()); 169 EXPECT_TRUE(Lock(allocation.get(), true));
187 EXPECT_FALSE(CanBePurged(discardable.get())); 170 EXPECT_FALSE(CanBePurged(allocation.get()));
188 } 171 }
189 172
190 TEST_F(DiscardableMemoryManagerTest, Overflow) { 173 TEST_F(DiscardableMemoryManagerTest, Overflow) {
191 { 174 {
192 size_t size = 1024; 175 size_t size = 1024u;
193 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); 176 const scoped_ptr<Allocation> allocation(CreateLocked(size));
194 EXPECT_TRUE(IsRegistered(discardable.get()));
195 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
196 EXPECT_EQ(1024u, BytesAllocated()); 177 EXPECT_EQ(1024u, BytesAllocated());
197 178
198 size_t massive_size = std::numeric_limits<size_t>::max(); 179 size_t massive_size = std::numeric_limits<size_t>::max();
199 const scoped_ptr<DiscardableMemory> massive_discardable( 180 const scoped_ptr<Allocation> massive_allocation(Create(massive_size));
200 CreateLockedMemory(massive_size)); 181 EXPECT_FALSE(Lock(massive_allocation.get(), true));
201 EXPECT_FALSE(massive_discardable);
202 EXPECT_EQ(1024u, BytesAllocated()); 182 EXPECT_EQ(1024u, BytesAllocated());
203 } 183 }
204 EXPECT_EQ(0u, BytesAllocated()); 184 EXPECT_EQ(0u, BytesAllocated());
205 } 185 }
206 186
207 class PermutationTestData { 187 class PermutationTestData {
208 public: 188 public:
209 PermutationTestData(unsigned d0, unsigned d1, unsigned d2) { 189 PermutationTestData(unsigned d0, unsigned d1, unsigned d2) {
210 ordering_[0] = d0; 190 ordering_[0] = d0;
211 ordering_[1] = d1; 191 ordering_[1] = d1;
212 ordering_[2] = d2; 192 ordering_[2] = d2;
213 } 193 }
214 194
215 const unsigned* ordering() const { return ordering_; } 195 const unsigned* ordering() const { return ordering_; }
216 196
217 private: 197 private:
218 unsigned ordering_[3]; 198 unsigned ordering_[3];
219 }; 199 };
220 200
221 class DiscardableMemoryManagerPermutationTest 201 class DiscardableMemoryManagerPermutationTest
222 : public DiscardableMemoryManagerTestBase, 202 : public DiscardableMemoryManagerTestBase,
223 public testing::TestWithParam<PermutationTestData> { 203 public testing::TestWithParam<PermutationTestData> {
224 public: 204 public:
225 DiscardableMemoryManagerPermutationTest() {} 205 DiscardableMemoryManagerPermutationTest() {}
226 206
227 protected: 207 protected:
228 // Use discardable memory in order specified by ordering parameter. 208 // Use discardable memory in order specified by ordering parameter.
229 void CreateAndUseDiscardableMemory() { 209 void CreateAndUseDiscardableMemory() {
230 for (int i = 0; i < 3; ++i) { 210 for (int i = 0; i < 3; ++i) {
231 discardables_[i] = CreateLockedMemory(1024); 211 allocations_[i] = CreateLocked(1024u);
232 EXPECT_TRUE(discardables_[i]); 212 Unlock(allocations_[i].get());
233 EXPECT_NE(static_cast<void*>(NULL), Memory(discardables_[i].get()));
234 discardables_[i]->Unlock();
235 } 213 }
236 for (int i = 0; i < 3; ++i) { 214 for (int i = 0; i < 3; ++i) {
237 int index = GetParam().ordering()[i]; 215 int index = GetParam().ordering()[i];
238 EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_FAILED, 216 EXPECT_TRUE(Lock(allocations_[index].get()));
239 discardables_[index]->Lock());
240 // Leave i == 0 locked. 217 // Leave i == 0 locked.
241 if (i > 0) 218 if (i > 0)
242 discardables_[index]->Unlock(); 219 Unlock(allocations_[index].get());
243 } 220 }
244 } 221 }
245 222
246 DiscardableMemory* discardable(unsigned position) { 223 Allocation* allocation(unsigned position) {
247 return discardables_[GetParam().ordering()[position]].get(); 224 return allocations_[GetParam().ordering()[position]].get();
248 } 225 }
249 226
250 private: 227 private:
251 scoped_ptr<DiscardableMemory> discardables_[3]; 228 scoped_ptr<Allocation> allocations_[3];
252 }; 229 };
253 230
254 // Verify that memory was discarded in the correct order after applying 231 // Verify that memory was discarded in the correct order after applying
255 // memory pressure. 232 // memory pressure.
256 TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedModeratePressure) { 233 TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedModeratePressure) {
257 CreateAndUseDiscardableMemory(); 234 CreateAndUseDiscardableMemory();
258 235
259 SetBytesToKeepUnderModeratePressure(1024); 236 SetDiscardableMemoryLimit(2048u);
260 SetDiscardableMemoryLimit(2048); 237 // Simulate moderate pressure by purging until usage is within 1024u bytes.
238 PurgeUntilUsageIsWithin(1024u);
261 239
262 MemoryPressureListener::NotifyMemoryPressure( 240 EXPECT_TRUE(Lock(allocation(2)));
263 MemoryPressureListener::MEMORY_PRESSURE_MODERATE); 241 EXPECT_TRUE(Lock(allocation(1), true));
264 RunLoop().RunUntilIdle();
265
266 EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_FAILED, discardable(2)->Lock());
267 EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS, discardable(1)->Lock());
268 // 0 should still be locked. 242 // 0 should still be locked.
269 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(0))); 243 EXPECT_FALSE(CanBePurged(allocation(0)));
270 } 244 }
271 245
272 // Verify that memory was discarded in the correct order after changing 246 // Verify that memory was discarded in the correct order after changing
273 // memory limit. 247 // memory limit.
274 TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedExceedLimit) { 248 TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedExceedLimit) {
275 CreateAndUseDiscardableMemory(); 249 CreateAndUseDiscardableMemory();
276 250
277 SetBytesToKeepUnderModeratePressure(1024); 251 SetDiscardableMemoryLimit(2048u);
278 SetDiscardableMemoryLimit(2048);
279 252
280 EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_FAILED, discardable(2)->Lock()); 253 EXPECT_TRUE(Lock(allocation(2)));
281 EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS, discardable(1)->Lock()); 254 EXPECT_TRUE(Lock(allocation(1), true));
282 // 0 should still be locked. 255 // 0 should still be locked.
283 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(0))); 256 EXPECT_FALSE(CanBePurged(allocation(0)));
284 } 257 }
285 258
286 // Verify that no more memory than necessary was discarded after changing 259 // Verify that no more memory than necessary was discarded after changing
287 // memory limit. 260 // memory limit.
288 TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedAmount) { 261 TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedAmount) {
289 SetBytesToKeepUnderModeratePressure(2048);
290 SetDiscardableMemoryLimit(4096);
291
292 CreateAndUseDiscardableMemory(); 262 CreateAndUseDiscardableMemory();
293 263
294 SetDiscardableMemoryLimit(2048); 264 SetDiscardableMemoryLimit(2048u);
295 265
296 EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS, discardable(2)->Lock()); 266 EXPECT_TRUE(Lock(allocation(2), false));
297 EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_PURGED, discardable(1)->Lock()); 267 EXPECT_TRUE(Lock(allocation(1), true));
298 // 0 should still be locked. 268 // 0 should still be locked.
299 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(0))); 269 EXPECT_FALSE(CanBePurged(allocation(0)));
300 } 270 }
301 271
302 TEST_P(DiscardableMemoryManagerPermutationTest, 272 TEST_P(DiscardableMemoryManagerPermutationTest, PurgeFreesAllUnlocked) {
303 CriticalPressureFreesAllUnlocked) {
304 CreateAndUseDiscardableMemory(); 273 CreateAndUseDiscardableMemory();
305 274
306 MemoryPressureListener::NotifyMemoryPressure( 275 PurgeUntilUsageIsWithin(0u);
307 MemoryPressureListener::MEMORY_PRESSURE_CRITICAL);
308 RunLoop().RunUntilIdle();
309 276
310 for (int i = 0; i < 3; ++i) { 277 for (int i = 0; i < 3; ++i) {
311 if (i == 0) 278 if (i == 0)
312 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(i))); 279 EXPECT_FALSE(CanBePurged(allocation(i)));
313 else 280 else
314 EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_PURGED, discardable(i)->Lock()); 281 EXPECT_TRUE(Lock(allocation(i), true));
315 } 282 }
316 } 283 }
317 284
318 INSTANTIATE_TEST_CASE_P(DiscardableMemoryManagerPermutationTests, 285 INSTANTIATE_TEST_CASE_P(DiscardableMemoryManagerPermutationTests,
319 DiscardableMemoryManagerPermutationTest, 286 DiscardableMemoryManagerPermutationTest,
320 ::testing::Values(PermutationTestData(0, 1, 2), 287 ::testing::Values(PermutationTestData(0, 1, 2),
321 PermutationTestData(0, 2, 1), 288 PermutationTestData(0, 2, 1),
322 PermutationTestData(1, 0, 2), 289 PermutationTestData(1, 0, 2),
323 PermutationTestData(1, 2, 0), 290 PermutationTestData(1, 2, 0),
324 PermutationTestData(2, 0, 1), 291 PermutationTestData(2, 0, 1),
325 PermutationTestData(2, 1, 0))); 292 PermutationTestData(2, 1, 0)));
326 293
327 TEST_F(DiscardableMemoryManagerTest, NormalDestruction) { 294 TEST_F(DiscardableMemoryManagerTest, NormalDestruction) {
328 { 295 {
329 size_t size = 1024; 296 size_t size = 1024u;
330 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); 297 const scoped_ptr<Allocation> allocation(CreateLocked(size));
331 EXPECT_TRUE(IsRegistered(discardable.get()));
332 EXPECT_EQ(1024u, BytesAllocated()); 298 EXPECT_EQ(1024u, BytesAllocated());
299 Unlock(allocation.get());
333 } 300 }
334 EXPECT_EQ(0u, BytesAllocated()); 301 EXPECT_EQ(0u, BytesAllocated());
335 } 302 }
336 303
337 TEST_F(DiscardableMemoryManagerTest, DestructionWhileLocked) { 304 TEST_F(DiscardableMemoryManagerTest, DestructionWhileLocked) {
338 { 305 {
339 size_t size = 1024; 306 size_t size = 1024u;
340 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); 307 const scoped_ptr<Allocation> allocation(CreateLocked(size));
341 EXPECT_TRUE(IsRegistered(discardable.get()));
342 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
343 EXPECT_EQ(1024u, BytesAllocated()); 308 EXPECT_EQ(1024u, BytesAllocated());
344 EXPECT_FALSE(CanBePurged(discardable.get())); 309 EXPECT_FALSE(CanBePurged(allocation.get()));
345 } 310 }
346 // Should have ignored the "locked" status and freed the discardable memory. 311 // Should have ignored the "locked" status and freed the discardable memory.
347 EXPECT_EQ(0u, BytesAllocated()); 312 EXPECT_EQ(0u, BytesAllocated());
348 } 313 }
349 314
350 #if !defined(NDEBUG) && !defined(OS_ANDROID) && !defined(OS_IOS)
351 // Death tests are not supported with Android APKs.
352 TEST_F(DiscardableMemoryManagerTest, UnlockedMemoryAccessCrashesInDebugMode) {
353 size_t size = 1024;
354 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size));
355 EXPECT_TRUE(IsRegistered(discardable.get()));
356 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
357 EXPECT_EQ(1024u, BytesAllocated());
358 EXPECT_FALSE(CanBePurged(discardable.get()));
359 discardable->Unlock();
360 EXPECT_TRUE(CanBePurged(discardable.get()));
361 // We *must* die if we are asked to vend a pointer to unlocked memory.
362 EXPECT_DEATH(discardable->Memory(), ".*Check failed.*");
363 }
364 #endif
365
366 class ThreadedDiscardableMemoryManagerTest 315 class ThreadedDiscardableMemoryManagerTest
367 : public DiscardableMemoryManagerTest { 316 : public DiscardableMemoryManagerTest {
368 public: 317 public:
369 ThreadedDiscardableMemoryManagerTest() 318 ThreadedDiscardableMemoryManagerTest()
370 : memory_usage_thread_("memory_usage_thread"), 319 : memory_usage_thread_("memory_usage_thread"),
371 thread_sync_(true, false) { 320 thread_sync_(true, false) {
372 } 321 }
373 322
374 virtual void SetUp() OVERRIDE { 323 virtual void SetUp() OVERRIDE {
375 memory_usage_thread_.Start(); 324 memory_usage_thread_.Start();
376 } 325 }
377 326
378 virtual void TearDown() OVERRIDE { 327 virtual void TearDown() OVERRIDE {
379 memory_usage_thread_.Stop(); 328 memory_usage_thread_.Stop();
380 } 329 }
381 330
382 void UseMemoryHelper() { 331 void UseMemoryHelper() {
383 size_t size = 1024; 332 size_t size = 1024u;
384 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); 333 const scoped_ptr<Allocation> allocation(CreateLocked(size));
385 EXPECT_TRUE(IsRegistered(discardable.get())); 334 Unlock(allocation.get());
386 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get()));
387 discardable->Unlock();
388 } 335 }
389 336
390 void SignalHelper() { 337 void SignalHelper() {
391 thread_sync_.Signal(); 338 thread_sync_.Signal();
392 } 339 }
393 340
394 Thread memory_usage_thread_; 341 Thread memory_usage_thread_;
395 WaitableEvent thread_sync_; 342 WaitableEvent thread_sync_;
396 }; 343 };
397 344
398 TEST_F(ThreadedDiscardableMemoryManagerTest, UseMemoryOnThread) { 345 TEST_F(ThreadedDiscardableMemoryManagerTest, UseMemoryOnThread) {
399 memory_usage_thread_.message_loop()->PostTask( 346 memory_usage_thread_.message_loop()->PostTask(
400 FROM_HERE, 347 FROM_HERE,
401 Bind(&ThreadedDiscardableMemoryManagerTest::UseMemoryHelper, 348 Bind(&ThreadedDiscardableMemoryManagerTest::UseMemoryHelper,
402 Unretained(this))); 349 Unretained(this)));
403 memory_usage_thread_.message_loop()->PostTask( 350 memory_usage_thread_.message_loop()->PostTask(
404 FROM_HERE, 351 FROM_HERE,
405 Bind(&ThreadedDiscardableMemoryManagerTest::SignalHelper, 352 Bind(&ThreadedDiscardableMemoryManagerTest::SignalHelper,
406 Unretained(this))); 353 Unretained(this)));
407 thread_sync_.Wait(); 354 thread_sync_.Wait();
408 } 355 }
409 356
410 } // namespace base 357 } // namespace base
OLDNEW
« base/memory/discardable_memory_manager.h ('K') | « base/memory/discardable_memory_manager.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698