OLD | NEW |
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 "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/run_loop.h" | |
9 #include "base/synchronization/waitable_event.h" | 8 #include "base/synchronization/waitable_event.h" |
10 #include "base/threading/thread.h" | 9 #include "base/threading/thread.h" |
11 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
12 | 11 |
13 namespace base { | 12 namespace base { |
14 namespace { | 13 namespace { |
15 | 14 |
16 class TestAllocationImpl : public internal::DiscardableMemoryManagerAllocation { | 15 class TestAllocationImpl : public internal::DiscardableMemoryManagerAllocation { |
17 public: | 16 public: |
18 TestAllocationImpl() : is_allocated_(false), is_locked_(false) {} | 17 TestAllocationImpl() : is_allocated_(false), is_locked_(false) {} |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 | 60 |
62 private: | 61 private: |
63 // Overriden from internal::DiscardableMemoryManager: | 62 // Overriden from internal::DiscardableMemoryManager: |
64 virtual TimeTicks Now() const OVERRIDE { return now_; } | 63 virtual TimeTicks Now() const OVERRIDE { return now_; } |
65 | 64 |
66 TimeTicks now_; | 65 TimeTicks now_; |
67 }; | 66 }; |
68 | 67 |
69 class DiscardableMemoryManagerTestBase { | 68 class DiscardableMemoryManagerTestBase { |
70 public: | 69 public: |
71 DiscardableMemoryManagerTestBase() { | 70 DiscardableMemoryManagerTestBase() {} |
72 manager_.RegisterMemoryPressureListener(); | |
73 } | |
74 | 71 |
75 protected: | 72 protected: |
76 enum LockStatus { | 73 enum LockStatus { |
77 LOCK_STATUS_FAILED, | 74 LOCK_STATUS_FAILED, |
78 LOCK_STATUS_PURGED, | 75 LOCK_STATUS_PURGED, |
79 LOCK_STATUS_SUCCESS | 76 LOCK_STATUS_SUCCESS |
80 }; | 77 }; |
81 | 78 |
82 size_t BytesAllocated() const { return manager_.GetBytesAllocatedForTest(); } | 79 size_t BytesAllocated() const { return manager_.GetBytesAllocatedForTest(); } |
83 | 80 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
120 manager_.Register(allocation, bytes); | 117 manager_.Register(allocation, bytes); |
121 return Lock(allocation); | 118 return Lock(allocation); |
122 } | 119 } |
123 | 120 |
124 bool CanBePurged(TestAllocationImpl* allocation) const { | 121 bool CanBePurged(TestAllocationImpl* allocation) const { |
125 return manager_.CanBePurgedForTest(allocation); | 122 return manager_.CanBePurgedForTest(allocation); |
126 } | 123 } |
127 | 124 |
128 void SetNow(TimeTicks now) { manager_.SetNow(now); } | 125 void SetNow(TimeTicks now) { manager_.SetNow(now); } |
129 | 126 |
| 127 void PurgeAll() { return manager_.PurgeAll(); } |
| 128 |
130 bool ReduceMemoryUsage() { return manager_.ReduceMemoryUsage(); } | 129 bool ReduceMemoryUsage() { return manager_.ReduceMemoryUsage(); } |
131 | 130 |
| 131 void ReduceMemoryUsageUntilWithinModeratePressureLimit() { |
| 132 manager_.ReduceMemoryUsageUntilWithinModeratePressureLimit(); |
| 133 } |
| 134 |
132 private: | 135 private: |
133 MessageLoopForIO message_loop_; | |
134 TestDiscardableMemoryManagerImpl manager_; | 136 TestDiscardableMemoryManagerImpl manager_; |
135 }; | 137 }; |
136 | 138 |
137 class DiscardableMemoryManagerTest : public DiscardableMemoryManagerTestBase, | 139 class DiscardableMemoryManagerTest : public DiscardableMemoryManagerTestBase, |
138 public testing::Test { | 140 public testing::Test { |
139 public: | 141 public: |
140 DiscardableMemoryManagerTest() {} | 142 DiscardableMemoryManagerTest() {} |
141 }; | 143 }; |
142 | 144 |
143 TEST_F(DiscardableMemoryManagerTest, CreateAndLock) { | 145 TEST_F(DiscardableMemoryManagerTest, CreateAndLock) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 TestAllocationImpl allocation; | 187 TestAllocationImpl allocation; |
186 RegisterAndLock(&allocation, size); | 188 RegisterAndLock(&allocation, size); |
187 EXPECT_EQ(1024u, BytesAllocated()); | 189 EXPECT_EQ(1024u, BytesAllocated()); |
188 EXPECT_FALSE(CanBePurged(&allocation)); | 190 EXPECT_FALSE(CanBePurged(&allocation)); |
189 | 191 |
190 // Now unlock so we can lock later. | 192 // Now unlock so we can lock later. |
191 Unlock(&allocation); | 193 Unlock(&allocation); |
192 EXPECT_TRUE(CanBePurged(&allocation)); | 194 EXPECT_TRUE(CanBePurged(&allocation)); |
193 | 195 |
194 // Force the system to purge. | 196 // Force the system to purge. |
195 MemoryPressureListener::NotifyMemoryPressure( | 197 PurgeAll(); |
196 MemoryPressureListener::MEMORY_PRESSURE_CRITICAL); | |
197 | |
198 // Required because ObserverListThreadSafe notifies via PostTask. | |
199 RunLoop().RunUntilIdle(); | |
200 | 198 |
201 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&allocation)); | 199 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&allocation)); |
202 EXPECT_FALSE(CanBePurged(&allocation)); | 200 EXPECT_FALSE(CanBePurged(&allocation)); |
203 | 201 |
204 Unlock(&allocation); | 202 Unlock(&allocation); |
205 Unregister(&allocation); | 203 Unregister(&allocation); |
206 } | 204 } |
207 | 205 |
208 TEST_F(DiscardableMemoryManagerTest, LockAfterPurgeAndCannotReallocate) { | 206 TEST_F(DiscardableMemoryManagerTest, LockAfterPurgeAndCannotReallocate) { |
209 size_t size = 1024; | 207 size_t size = 1024; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 if (allocation_[i].is_locked()) | 292 if (allocation_[i].is_locked()) |
295 Unlock(&allocation_[i]); | 293 Unlock(&allocation_[i]); |
296 Unregister(&allocation_[i]); | 294 Unregister(&allocation_[i]); |
297 } | 295 } |
298 } | 296 } |
299 | 297 |
300 private: | 298 private: |
301 TestAllocationImpl allocation_[3]; | 299 TestAllocationImpl allocation_[3]; |
302 }; | 300 }; |
303 | 301 |
304 // Verify that memory was discarded in the correct order after applying | 302 // Verify that memory was discarded in the correct order after reducing usage to |
305 // memory pressure. | 303 // moderate pressure limit. |
306 TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedModeratePressure) { | 304 TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedModeratePressure) { |
307 RegisterAndUseAllocations(); | 305 RegisterAndUseAllocations(); |
308 | 306 |
309 SetBytesToKeepUnderModeratePressure(1024); | 307 SetBytesToKeepUnderModeratePressure(1024); |
310 SetMemoryLimit(2048); | 308 SetMemoryLimit(2048); |
311 | 309 |
312 MemoryPressureListener::NotifyMemoryPressure( | 310 ReduceMemoryUsageUntilWithinModeratePressureLimit(); |
313 MemoryPressureListener::MEMORY_PRESSURE_MODERATE); | |
314 RunLoop().RunUntilIdle(); | |
315 | 311 |
316 EXPECT_NE(LOCK_STATUS_FAILED, Lock(allocation(2))); | 312 EXPECT_NE(LOCK_STATUS_FAILED, Lock(allocation(2))); |
317 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1))); | 313 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1))); |
318 // 0 should still be locked. | 314 // 0 should still be locked. |
319 EXPECT_TRUE(allocation(0)->is_locked()); | 315 EXPECT_TRUE(allocation(0)->is_locked()); |
320 | 316 |
321 UnlockAndUnregisterAllocations(); | 317 UnlockAndUnregisterAllocations(); |
322 } | 318 } |
323 | 319 |
324 // Verify that memory was discarded in the correct order after changing | 320 // Verify that memory was discarded in the correct order after changing |
(...skipping 26 matching lines...) Expand all Loading... |
351 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1))); | 347 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1))); |
352 // 0 should still be locked. | 348 // 0 should still be locked. |
353 EXPECT_TRUE(allocation(0)->is_locked()); | 349 EXPECT_TRUE(allocation(0)->is_locked()); |
354 | 350 |
355 UnlockAndUnregisterAllocations(); | 351 UnlockAndUnregisterAllocations(); |
356 } | 352 } |
357 | 353 |
358 TEST_P(DiscardableMemoryManagerPermutationTest, PurgeFreesAllUnlocked) { | 354 TEST_P(DiscardableMemoryManagerPermutationTest, PurgeFreesAllUnlocked) { |
359 RegisterAndUseAllocations(); | 355 RegisterAndUseAllocations(); |
360 | 356 |
361 MemoryPressureListener::NotifyMemoryPressure( | 357 PurgeAll(); |
362 MemoryPressureListener::MEMORY_PRESSURE_CRITICAL); | |
363 RunLoop().RunUntilIdle(); | |
364 | 358 |
365 for (int i = 0; i < 3; ++i) { | 359 for (int i = 0; i < 3; ++i) { |
366 if (i == 0) | 360 if (i == 0) |
367 EXPECT_TRUE(allocation(i)->is_locked()); | 361 EXPECT_TRUE(allocation(i)->is_locked()); |
368 else | 362 else |
369 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(i))); | 363 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(i))); |
370 } | 364 } |
371 | 365 |
372 UnlockAndUnregisterAllocations(); | 366 UnlockAndUnregisterAllocations(); |
373 } | 367 } |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 Unretained(this))); | 490 Unretained(this))); |
497 memory_usage_thread_.message_loop()->PostTask( | 491 memory_usage_thread_.message_loop()->PostTask( |
498 FROM_HERE, | 492 FROM_HERE, |
499 Bind(&ThreadedDiscardableMemoryManagerTest::SignalHelper, | 493 Bind(&ThreadedDiscardableMemoryManagerTest::SignalHelper, |
500 Unretained(this))); | 494 Unretained(this))); |
501 thread_sync_.Wait(); | 495 thread_sync_.Wait(); |
502 } | 496 } |
503 | 497 |
504 } // namespace | 498 } // namespace |
505 } // namespace base | 499 } // namespace base |
OLD | NEW |