OLD | NEW |
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_provider.h" | 5 #include "base/memory/discardable_memory_provider.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/discardable_memory.h" | 8 #include "base/memory/discardable_memory.h" |
9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
10 #include "base/synchronization/waitable_event.h" | 10 #include "base/synchronization/waitable_event.h" |
(...skipping 13 matching lines...) Expand all Loading... |
24 provider_->Register(this, size); | 24 provider_->Register(this, size); |
25 } | 25 } |
26 | 26 |
27 virtual ~TestDiscardableMemory() { | 27 virtual ~TestDiscardableMemory() { |
28 if (is_locked_) | 28 if (is_locked_) |
29 Unlock(); | 29 Unlock(); |
30 provider_->Unregister(this); | 30 provider_->Unregister(this); |
31 } | 31 } |
32 | 32 |
33 // Overridden from DiscardableMemory: | 33 // Overridden from DiscardableMemory: |
34 virtual LockDiscardableMemoryStatus Lock() OVERRIDE { | 34 virtual DiscardableMemoryLockStatus Lock() OVERRIDE { |
35 DCHECK(!is_locked_); | 35 DCHECK(!is_locked_); |
36 | 36 |
37 bool purged = false; | 37 bool purged = false; |
38 memory_ = provider_->Acquire(this, &purged); | 38 memory_ = provider_->Acquire(this, &purged); |
39 if (!memory_) | 39 if (!memory_) |
40 return DISCARDABLE_MEMORY_FAILED; | 40 return DISCARDABLE_MEMORY_LOCK_STATUS_FAILED; |
41 | 41 |
42 is_locked_ = true; | 42 is_locked_ = true; |
43 return purged ? DISCARDABLE_MEMORY_PURGED : DISCARDABLE_MEMORY_SUCCESS; | 43 return purged ? DISCARDABLE_MEMORY_LOCK_STATUS_PURGED |
| 44 : DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS; |
44 } | 45 } |
45 virtual void Unlock() OVERRIDE { | 46 virtual void Unlock() OVERRIDE { |
46 DCHECK(is_locked_); | 47 DCHECK(is_locked_); |
47 provider_->Release(this, memory_.Pass()); | 48 provider_->Release(this, memory_.Pass()); |
48 is_locked_ = false; | 49 is_locked_ = false; |
49 } | 50 } |
50 virtual void* Memory() const OVERRIDE { | 51 virtual void* Memory() const OVERRIDE { |
51 DCHECK(memory_); | 52 DCHECK(memory_); |
52 return memory_.get(); | 53 return memory_.get(); |
53 } | 54 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 provider_->SetDiscardableMemoryLimit(bytes); | 87 provider_->SetDiscardableMemoryLimit(bytes); |
87 } | 88 } |
88 | 89 |
89 void SetBytesToReclaimUnderModeratePressure(size_t bytes) { | 90 void SetBytesToReclaimUnderModeratePressure(size_t bytes) { |
90 provider_->SetBytesToReclaimUnderModeratePressure(bytes); | 91 provider_->SetBytesToReclaimUnderModeratePressure(bytes); |
91 } | 92 } |
92 | 93 |
93 scoped_ptr<DiscardableMemory> CreateLockedMemory(size_t size) { | 94 scoped_ptr<DiscardableMemory> CreateLockedMemory(size_t size) { |
94 scoped_ptr<TestDiscardableMemory> memory( | 95 scoped_ptr<TestDiscardableMemory> memory( |
95 new TestDiscardableMemory(provider_.get(), size)); | 96 new TestDiscardableMemory(provider_.get(), size)); |
96 if (memory->Lock() != DISCARDABLE_MEMORY_PURGED) | 97 if (memory->Lock() != DISCARDABLE_MEMORY_LOCK_STATUS_PURGED) |
97 return scoped_ptr<DiscardableMemory>(); | 98 return scoped_ptr<DiscardableMemory>(); |
98 return memory.PassAs<DiscardableMemory>(); | 99 return memory.PassAs<DiscardableMemory>(); |
99 } | 100 } |
100 | 101 |
101 private: | 102 private: |
102 MessageLoop message_loop_; | 103 MessageLoop message_loop_; |
103 scoped_ptr<internal::DiscardableMemoryProvider> provider_; | 104 scoped_ptr<internal::DiscardableMemoryProvider> provider_; |
104 }; | 105 }; |
105 | 106 |
106 class DiscardableMemoryProviderTest | 107 class DiscardableMemoryProviderTest |
(...skipping 25 matching lines...) Expand all Loading... |
132 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); | 133 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); |
133 EXPECT_TRUE(IsRegistered(discardable.get())); | 134 EXPECT_TRUE(IsRegistered(discardable.get())); |
134 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get())); | 135 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get())); |
135 EXPECT_EQ(1024u, BytesAllocated()); | 136 EXPECT_EQ(1024u, BytesAllocated()); |
136 EXPECT_FALSE(CanBePurged(discardable.get())); | 137 EXPECT_FALSE(CanBePurged(discardable.get())); |
137 | 138 |
138 // Now unlock so we can lock later. | 139 // Now unlock so we can lock later. |
139 discardable->Unlock(); | 140 discardable->Unlock(); |
140 EXPECT_TRUE(CanBePurged(discardable.get())); | 141 EXPECT_TRUE(CanBePurged(discardable.get())); |
141 | 142 |
142 EXPECT_EQ(DISCARDABLE_MEMORY_SUCCESS, discardable->Lock()); | 143 EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS, discardable->Lock()); |
143 EXPECT_FALSE(CanBePurged(discardable.get())); | 144 EXPECT_FALSE(CanBePurged(discardable.get())); |
144 } | 145 } |
145 | 146 |
146 TEST_F(DiscardableMemoryProviderTest, LockAfterPurge) { | 147 TEST_F(DiscardableMemoryProviderTest, LockAfterPurge) { |
147 size_t size = 1024; | 148 size_t size = 1024; |
148 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); | 149 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); |
149 EXPECT_TRUE(IsRegistered(discardable.get())); | 150 EXPECT_TRUE(IsRegistered(discardable.get())); |
150 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get())); | 151 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get())); |
151 EXPECT_EQ(1024u, BytesAllocated()); | 152 EXPECT_EQ(1024u, BytesAllocated()); |
152 EXPECT_FALSE(CanBePurged(discardable.get())); | 153 EXPECT_FALSE(CanBePurged(discardable.get())); |
153 | 154 |
154 // Now unlock so we can lock later. | 155 // Now unlock so we can lock later. |
155 discardable->Unlock(); | 156 discardable->Unlock(); |
156 EXPECT_TRUE(CanBePurged(discardable.get())); | 157 EXPECT_TRUE(CanBePurged(discardable.get())); |
157 | 158 |
158 // Force the system to purge. | 159 // Force the system to purge. |
159 MemoryPressureListener::NotifyMemoryPressure( | 160 MemoryPressureListener::NotifyMemoryPressure( |
160 MemoryPressureListener::MEMORY_PRESSURE_CRITICAL); | 161 MemoryPressureListener::MEMORY_PRESSURE_CRITICAL); |
161 | 162 |
162 // Required because ObserverListThreadSafe notifies via PostTask. | 163 // Required because ObserverListThreadSafe notifies via PostTask. |
163 RunLoop().RunUntilIdle(); | 164 RunLoop().RunUntilIdle(); |
164 | 165 |
165 EXPECT_EQ(DISCARDABLE_MEMORY_PURGED, discardable->Lock()); | 166 EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_PURGED, discardable->Lock()); |
166 EXPECT_FALSE(CanBePurged(discardable.get())); | 167 EXPECT_FALSE(CanBePurged(discardable.get())); |
167 } | 168 } |
168 | 169 |
169 TEST_F(DiscardableMemoryProviderTest, LockAfterPurgeAndCannotReallocate) { | 170 TEST_F(DiscardableMemoryProviderTest, LockAfterPurgeAndCannotReallocate) { |
170 size_t size = 1024; | 171 size_t size = 1024; |
171 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); | 172 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); |
172 EXPECT_TRUE(IsRegistered(discardable.get())); | 173 EXPECT_TRUE(IsRegistered(discardable.get())); |
173 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get())); | 174 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get())); |
174 EXPECT_EQ(1024u, BytesAllocated()); | 175 EXPECT_EQ(1024u, BytesAllocated()); |
175 EXPECT_FALSE(CanBePurged(discardable.get())); | 176 EXPECT_FALSE(CanBePurged(discardable.get())); |
176 | 177 |
177 // Now unlock so we can lock later. | 178 // Now unlock so we can lock later. |
178 discardable->Unlock(); | 179 discardable->Unlock(); |
179 EXPECT_TRUE(CanBePurged(discardable.get())); | 180 EXPECT_TRUE(CanBePurged(discardable.get())); |
180 | 181 |
181 // Set max allowed allocation to 1 byte. This will make cause the memory | 182 // Set max allowed allocation to 1 byte. This will make cause the memory |
182 // to be purged. | 183 // to be purged. |
183 SetDiscardableMemoryLimit(1); | 184 SetDiscardableMemoryLimit(1); |
184 | 185 |
185 EXPECT_EQ(DISCARDABLE_MEMORY_PURGED, discardable->Lock()); | 186 EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_PURGED, discardable->Lock()); |
186 EXPECT_FALSE(CanBePurged(discardable.get())); | 187 EXPECT_FALSE(CanBePurged(discardable.get())); |
187 } | 188 } |
188 | 189 |
189 TEST_F(DiscardableMemoryProviderTest, Overflow) { | 190 TEST_F(DiscardableMemoryProviderTest, Overflow) { |
190 { | 191 { |
191 size_t size = 1024; | 192 size_t size = 1024; |
192 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); | 193 const scoped_ptr<DiscardableMemory> discardable(CreateLockedMemory(size)); |
193 EXPECT_TRUE(IsRegistered(discardable.get())); | 194 EXPECT_TRUE(IsRegistered(discardable.get())); |
194 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get())); | 195 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable.get())); |
195 EXPECT_EQ(1024u, BytesAllocated()); | 196 EXPECT_EQ(1024u, BytesAllocated()); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 // Use discardable memory in order specified by ordering parameter. | 228 // Use discardable memory in order specified by ordering parameter. |
228 void CreateAndUseDiscardableMemory() { | 229 void CreateAndUseDiscardableMemory() { |
229 for (int i = 0; i < 3; ++i) { | 230 for (int i = 0; i < 3; ++i) { |
230 discardables_[i] = CreateLockedMemory(1024); | 231 discardables_[i] = CreateLockedMemory(1024); |
231 EXPECT_TRUE(discardables_[i]); | 232 EXPECT_TRUE(discardables_[i]); |
232 EXPECT_NE(static_cast<void*>(NULL), Memory(discardables_[i].get())); | 233 EXPECT_NE(static_cast<void*>(NULL), Memory(discardables_[i].get())); |
233 discardables_[i]->Unlock(); | 234 discardables_[i]->Unlock(); |
234 } | 235 } |
235 for (int i = 0; i < 3; ++i) { | 236 for (int i = 0; i < 3; ++i) { |
236 int index = GetParam().ordering()[i]; | 237 int index = GetParam().ordering()[i]; |
237 EXPECT_NE(DISCARDABLE_MEMORY_FAILED, discardables_[index]->Lock()); | 238 EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_FAILED, |
| 239 discardables_[index]->Lock()); |
238 // Leave i == 0 locked. | 240 // Leave i == 0 locked. |
239 if (i > 0) | 241 if (i > 0) |
240 discardables_[index]->Unlock(); | 242 discardables_[index]->Unlock(); |
241 } | 243 } |
242 } | 244 } |
243 | 245 |
244 DiscardableMemory* discardable(unsigned position) { | 246 DiscardableMemory* discardable(unsigned position) { |
245 return discardables_[GetParam().ordering()[position]].get(); | 247 return discardables_[GetParam().ordering()[position]].get(); |
246 } | 248 } |
247 | 249 |
248 private: | 250 private: |
249 scoped_ptr<DiscardableMemory> discardables_[3]; | 251 scoped_ptr<DiscardableMemory> discardables_[3]; |
250 }; | 252 }; |
251 | 253 |
252 // Verify that memory was discarded in the correct order after applying | 254 // Verify that memory was discarded in the correct order after applying |
253 // memory pressure. | 255 // memory pressure. |
254 TEST_P(DiscardableMemoryProviderPermutationTest, LRUDiscardedModeratePressure) { | 256 TEST_P(DiscardableMemoryProviderPermutationTest, LRUDiscardedModeratePressure) { |
255 CreateAndUseDiscardableMemory(); | 257 CreateAndUseDiscardableMemory(); |
256 | 258 |
257 SetBytesToReclaimUnderModeratePressure(1024); | 259 SetBytesToReclaimUnderModeratePressure(1024); |
258 MemoryPressureListener::NotifyMemoryPressure( | 260 MemoryPressureListener::NotifyMemoryPressure( |
259 MemoryPressureListener::MEMORY_PRESSURE_MODERATE); | 261 MemoryPressureListener::MEMORY_PRESSURE_MODERATE); |
260 RunLoop().RunUntilIdle(); | 262 RunLoop().RunUntilIdle(); |
261 | 263 |
262 EXPECT_NE(DISCARDABLE_MEMORY_FAILED, discardable(2)->Lock()); | 264 EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_FAILED, discardable(2)->Lock()); |
263 EXPECT_NE(DISCARDABLE_MEMORY_SUCCESS, discardable(1)->Lock()); | 265 EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS, discardable(1)->Lock()); |
264 // 0 should still be locked. | 266 // 0 should still be locked. |
265 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(0))); | 267 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(0))); |
266 } | 268 } |
267 | 269 |
268 // Verify that memory was discarded in the correct order after changing | 270 // Verify that memory was discarded in the correct order after changing |
269 // memory limit. | 271 // memory limit. |
270 TEST_P(DiscardableMemoryProviderPermutationTest, LRUDiscardedExceedLimit) { | 272 TEST_P(DiscardableMemoryProviderPermutationTest, LRUDiscardedExceedLimit) { |
271 CreateAndUseDiscardableMemory(); | 273 CreateAndUseDiscardableMemory(); |
272 | 274 |
273 SetBytesToReclaimUnderModeratePressure(1024); | 275 SetBytesToReclaimUnderModeratePressure(1024); |
274 SetDiscardableMemoryLimit(2048); | 276 SetDiscardableMemoryLimit(2048); |
275 | 277 |
276 EXPECT_NE(DISCARDABLE_MEMORY_FAILED, discardable(2)->Lock()); | 278 EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_FAILED, discardable(2)->Lock()); |
277 EXPECT_NE(DISCARDABLE_MEMORY_SUCCESS, discardable(1)->Lock()); | 279 EXPECT_NE(DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS, discardable(1)->Lock()); |
278 // 0 should still be locked. | 280 // 0 should still be locked. |
279 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(0))); | 281 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(0))); |
280 } | 282 } |
281 | 283 |
282 // Verify that no more memory than necessary was discarded after changing | 284 // Verify that no more memory than necessary was discarded after changing |
283 // memory limit. | 285 // memory limit. |
284 TEST_P(DiscardableMemoryProviderPermutationTest, LRUDiscardedAmount) { | 286 TEST_P(DiscardableMemoryProviderPermutationTest, LRUDiscardedAmount) { |
285 SetBytesToReclaimUnderModeratePressure(2048); | 287 SetBytesToReclaimUnderModeratePressure(2048); |
286 SetDiscardableMemoryLimit(4096); | 288 SetDiscardableMemoryLimit(4096); |
287 | 289 |
288 CreateAndUseDiscardableMemory(); | 290 CreateAndUseDiscardableMemory(); |
289 | 291 |
290 SetDiscardableMemoryLimit(2048); | 292 SetDiscardableMemoryLimit(2048); |
291 | 293 |
292 EXPECT_EQ(DISCARDABLE_MEMORY_SUCCESS, discardable(2)->Lock()); | 294 EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_SUCCESS, discardable(2)->Lock()); |
293 EXPECT_EQ(DISCARDABLE_MEMORY_PURGED, discardable(1)->Lock()); | 295 EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_PURGED, discardable(1)->Lock()); |
294 // 0 should still be locked. | 296 // 0 should still be locked. |
295 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(0))); | 297 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(0))); |
296 } | 298 } |
297 | 299 |
298 TEST_P(DiscardableMemoryProviderPermutationTest, | 300 TEST_P(DiscardableMemoryProviderPermutationTest, |
299 CriticalPressureFreesAllUnlocked) { | 301 CriticalPressureFreesAllUnlocked) { |
300 CreateAndUseDiscardableMemory(); | 302 CreateAndUseDiscardableMemory(); |
301 | 303 |
302 MemoryPressureListener::NotifyMemoryPressure( | 304 MemoryPressureListener::NotifyMemoryPressure( |
303 MemoryPressureListener::MEMORY_PRESSURE_CRITICAL); | 305 MemoryPressureListener::MEMORY_PRESSURE_CRITICAL); |
304 RunLoop().RunUntilIdle(); | 306 RunLoop().RunUntilIdle(); |
305 | 307 |
306 for (int i = 0; i < 3; ++i) { | 308 for (int i = 0; i < 3; ++i) { |
307 if (i == 0) | 309 if (i == 0) |
308 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(i))); | 310 EXPECT_NE(static_cast<void*>(NULL), Memory(discardable(i))); |
309 else | 311 else |
310 EXPECT_EQ(DISCARDABLE_MEMORY_PURGED, discardable(i)->Lock()); | 312 EXPECT_EQ(DISCARDABLE_MEMORY_LOCK_STATUS_PURGED, discardable(i)->Lock()); |
311 } | 313 } |
312 } | 314 } |
313 | 315 |
314 INSTANTIATE_TEST_CASE_P(DiscardableMemoryProviderPermutationTests, | 316 INSTANTIATE_TEST_CASE_P(DiscardableMemoryProviderPermutationTests, |
315 DiscardableMemoryProviderPermutationTest, | 317 DiscardableMemoryProviderPermutationTest, |
316 ::testing::Values(PermutationTestData(0, 1, 2), | 318 ::testing::Values(PermutationTestData(0, 1, 2), |
317 PermutationTestData(0, 2, 1), | 319 PermutationTestData(0, 2, 1), |
318 PermutationTestData(1, 0, 2), | 320 PermutationTestData(1, 0, 2), |
319 PermutationTestData(1, 2, 0), | 321 PermutationTestData(1, 2, 0), |
320 PermutationTestData(2, 0, 1), | 322 PermutationTestData(2, 0, 1), |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 Bind(&ThreadedDiscardableMemoryProviderTest::UseMemoryHelper, | 399 Bind(&ThreadedDiscardableMemoryProviderTest::UseMemoryHelper, |
398 Unretained(this))); | 400 Unretained(this))); |
399 memory_usage_thread_.message_loop()->PostTask( | 401 memory_usage_thread_.message_loop()->PostTask( |
400 FROM_HERE, | 402 FROM_HERE, |
401 Bind(&ThreadedDiscardableMemoryProviderTest::SignalHelper, | 403 Bind(&ThreadedDiscardableMemoryProviderTest::SignalHelper, |
402 Unretained(this))); | 404 Unretained(this))); |
403 thread_sync_.Wait(); | 405 thread_sync_.Wait(); |
404 } | 406 } |
405 | 407 |
406 } // namespace base | 408 } // namespace base |
OLD | NEW |