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

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

Issue 448173002: Re-land: base: Introduce an explicit call for reducing emulated discardable memory usage. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: disable EmulatedDiscardableMemoryDiscardedWhenWidgetsHidden with lsan Created 6 years, 4 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
« no previous file with comments | « base/memory/discardable_memory_manager.cc ('k') | base/memory/discardable_memory_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 20 matching lines...) Expand all
39 38
40 private: 39 private:
41 bool is_allocated_; 40 bool is_allocated_;
42 bool is_locked_; 41 bool is_locked_;
43 }; 42 };
44 43
45 // Tests can assume that the default limit is at least 1024. Tests that rely on 44 // Tests can assume that the default limit is at least 1024. Tests that rely on
46 // something else needs to explicit set the limit. 45 // something else needs to explicit set the limit.
47 const size_t kDefaultMemoryLimit = 1024; 46 const size_t kDefaultMemoryLimit = 1024;
48 const size_t kDefaultSoftMemoryLimit = kDefaultMemoryLimit; 47 const size_t kDefaultSoftMemoryLimit = kDefaultMemoryLimit;
49 const size_t kDefaultBytesToKeepUnderModeratePressure = kDefaultMemoryLimit;
50 48
51 class TestDiscardableMemoryManagerImpl 49 class TestDiscardableMemoryManagerImpl
52 : public internal::DiscardableMemoryManager { 50 : public internal::DiscardableMemoryManager {
53 public: 51 public:
54 TestDiscardableMemoryManagerImpl() 52 TestDiscardableMemoryManagerImpl()
55 : DiscardableMemoryManager(kDefaultMemoryLimit, 53 : DiscardableMemoryManager(kDefaultMemoryLimit,
56 kDefaultSoftMemoryLimit, 54 kDefaultSoftMemoryLimit,
57 kDefaultBytesToKeepUnderModeratePressure,
58 TimeDelta::Max()) {} 55 TimeDelta::Max()) {}
59 56
60 void SetNow(TimeTicks now) { now_ = now; } 57 void SetNow(TimeTicks now) { now_ = now; }
61 58
62 private: 59 private:
63 // Overriden from internal::DiscardableMemoryManager: 60 // Overriden from internal::DiscardableMemoryManager:
64 virtual TimeTicks Now() const OVERRIDE { return now_; } 61 virtual TimeTicks Now() const OVERRIDE { return now_; }
65 62
66 TimeTicks now_; 63 TimeTicks now_;
67 }; 64 };
68 65
69 class DiscardableMemoryManagerTestBase { 66 class DiscardableMemoryManagerTestBase {
70 public: 67 public:
71 DiscardableMemoryManagerTestBase() { 68 DiscardableMemoryManagerTestBase() {}
72 manager_.RegisterMemoryPressureListener();
73 }
74 69
75 protected: 70 protected:
76 enum LockStatus { 71 enum LockStatus {
77 LOCK_STATUS_FAILED, 72 LOCK_STATUS_FAILED,
78 LOCK_STATUS_PURGED, 73 LOCK_STATUS_PURGED,
79 LOCK_STATUS_SUCCESS 74 LOCK_STATUS_SUCCESS
80 }; 75 };
81 76
82 size_t BytesAllocated() const { return manager_.GetBytesAllocatedForTest(); } 77 size_t BytesAllocated() const { return manager_.GetBytesAllocatedForTest(); }
83 78
84 void SetMemoryLimit(size_t bytes) { manager_.SetMemoryLimit(bytes); } 79 void SetMemoryLimit(size_t bytes) { manager_.SetMemoryLimit(bytes); }
85 80
86 void SetSoftMemoryLimit(size_t bytes) { manager_.SetSoftMemoryLimit(bytes); } 81 void SetSoftMemoryLimit(size_t bytes) { manager_.SetSoftMemoryLimit(bytes); }
87 82
88 void SetBytesToKeepUnderModeratePressure(size_t bytes) {
89 manager_.SetBytesToKeepUnderModeratePressure(bytes);
90 }
91
92 void SetHardMemoryLimitExpirationTime(TimeDelta time) { 83 void SetHardMemoryLimitExpirationTime(TimeDelta time) {
93 manager_.SetHardMemoryLimitExpirationTime(time); 84 manager_.SetHardMemoryLimitExpirationTime(time);
94 } 85 }
95 86
96 void Register(TestAllocationImpl* allocation, size_t bytes) { 87 void Register(TestAllocationImpl* allocation, size_t bytes) {
97 manager_.Register(allocation, bytes); 88 manager_.Register(allocation, bytes);
98 } 89 }
99 90
100 void Unregister(TestAllocationImpl* allocation) { 91 void Unregister(TestAllocationImpl* allocation) {
101 manager_.Unregister(allocation); 92 manager_.Unregister(allocation);
(...skipping 18 matching lines...) Expand all
120 manager_.Register(allocation, bytes); 111 manager_.Register(allocation, bytes);
121 return Lock(allocation); 112 return Lock(allocation);
122 } 113 }
123 114
124 bool CanBePurged(TestAllocationImpl* allocation) const { 115 bool CanBePurged(TestAllocationImpl* allocation) const {
125 return manager_.CanBePurgedForTest(allocation); 116 return manager_.CanBePurgedForTest(allocation);
126 } 117 }
127 118
128 void SetNow(TimeTicks now) { manager_.SetNow(now); } 119 void SetNow(TimeTicks now) { manager_.SetNow(now); }
129 120
121 void PurgeAll() { return manager_.PurgeAll(); }
122
130 bool ReduceMemoryUsage() { return manager_.ReduceMemoryUsage(); } 123 bool ReduceMemoryUsage() { return manager_.ReduceMemoryUsage(); }
131 124
125 void ReduceMemoryUsageUntilWithinLimit(size_t bytes) {
126 manager_.ReduceMemoryUsageUntilWithinLimit(bytes);
127 }
128
132 private: 129 private:
133 MessageLoopForIO message_loop_;
134 TestDiscardableMemoryManagerImpl manager_; 130 TestDiscardableMemoryManagerImpl manager_;
135 }; 131 };
136 132
137 class DiscardableMemoryManagerTest : public DiscardableMemoryManagerTestBase, 133 class DiscardableMemoryManagerTest : public DiscardableMemoryManagerTestBase,
138 public testing::Test { 134 public testing::Test {
139 public: 135 public:
140 DiscardableMemoryManagerTest() {} 136 DiscardableMemoryManagerTest() {}
141 }; 137 };
142 138
143 TEST_F(DiscardableMemoryManagerTest, CreateAndLock) { 139 TEST_F(DiscardableMemoryManagerTest, CreateAndLock) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 TestAllocationImpl allocation; 181 TestAllocationImpl allocation;
186 RegisterAndLock(&allocation, size); 182 RegisterAndLock(&allocation, size);
187 EXPECT_EQ(1024u, BytesAllocated()); 183 EXPECT_EQ(1024u, BytesAllocated());
188 EXPECT_FALSE(CanBePurged(&allocation)); 184 EXPECT_FALSE(CanBePurged(&allocation));
189 185
190 // Now unlock so we can lock later. 186 // Now unlock so we can lock later.
191 Unlock(&allocation); 187 Unlock(&allocation);
192 EXPECT_TRUE(CanBePurged(&allocation)); 188 EXPECT_TRUE(CanBePurged(&allocation));
193 189
194 // Force the system to purge. 190 // Force the system to purge.
195 MemoryPressureListener::NotifyMemoryPressure( 191 PurgeAll();
196 MemoryPressureListener::MEMORY_PRESSURE_CRITICAL);
197
198 // Required because ObserverListThreadSafe notifies via PostTask.
199 RunLoop().RunUntilIdle();
200 192
201 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&allocation)); 193 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(&allocation));
202 EXPECT_FALSE(CanBePurged(&allocation)); 194 EXPECT_FALSE(CanBePurged(&allocation));
203 195
204 Unlock(&allocation); 196 Unlock(&allocation);
205 Unregister(&allocation); 197 Unregister(&allocation);
206 } 198 }
207 199
208 TEST_F(DiscardableMemoryManagerTest, LockAfterPurgeAndCannotReallocate) { 200 TEST_F(DiscardableMemoryManagerTest, LockAfterPurgeAndCannotReallocate) {
209 size_t size = 1024; 201 size_t size = 1024;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 if (allocation_[i].is_locked()) 286 if (allocation_[i].is_locked())
295 Unlock(&allocation_[i]); 287 Unlock(&allocation_[i]);
296 Unregister(&allocation_[i]); 288 Unregister(&allocation_[i]);
297 } 289 }
298 } 290 }
299 291
300 private: 292 private:
301 TestAllocationImpl allocation_[3]; 293 TestAllocationImpl allocation_[3];
302 }; 294 };
303 295
304 // Verify that memory was discarded in the correct order after applying 296 // Verify that memory was discarded in the correct order after reducing usage to
305 // memory pressure. 297 // limit.
306 TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedModeratePressure) { 298 TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscarded) {
307 RegisterAndUseAllocations(); 299 RegisterAndUseAllocations();
308 300
309 SetBytesToKeepUnderModeratePressure(1024);
310 SetMemoryLimit(2048); 301 SetMemoryLimit(2048);
311 302
312 MemoryPressureListener::NotifyMemoryPressure( 303 ReduceMemoryUsageUntilWithinLimit(1024);
313 MemoryPressureListener::MEMORY_PRESSURE_MODERATE);
314 RunLoop().RunUntilIdle();
315 304
316 EXPECT_NE(LOCK_STATUS_FAILED, Lock(allocation(2))); 305 EXPECT_NE(LOCK_STATUS_FAILED, Lock(allocation(2)));
317 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1))); 306 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1)));
318 // 0 should still be locked. 307 // 0 should still be locked.
319 EXPECT_TRUE(allocation(0)->is_locked()); 308 EXPECT_TRUE(allocation(0)->is_locked());
320 309
321 UnlockAndUnregisterAllocations(); 310 UnlockAndUnregisterAllocations();
322 } 311 }
323 312
324 // Verify that memory was discarded in the correct order after changing 313 // Verify that memory was discarded in the correct order after changing
325 // memory limit. 314 // memory limit.
326 TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedExceedLimit) { 315 TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedExceedLimit) {
327 RegisterAndUseAllocations(); 316 RegisterAndUseAllocations();
328 317
329 SetBytesToKeepUnderModeratePressure(1024);
330 SetMemoryLimit(2048); 318 SetMemoryLimit(2048);
331 319
332 EXPECT_NE(LOCK_STATUS_FAILED, Lock(allocation(2))); 320 EXPECT_NE(LOCK_STATUS_FAILED, Lock(allocation(2)));
333 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1))); 321 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1)));
334 // 0 should still be locked. 322 // 0 should still be locked.
335 EXPECT_TRUE(allocation(0)->is_locked()); 323 EXPECT_TRUE(allocation(0)->is_locked());
336 324
337 UnlockAndUnregisterAllocations(); 325 UnlockAndUnregisterAllocations();
338 } 326 }
339 327
340 // Verify that no more memory than necessary was discarded after changing 328 // Verify that no more memory than necessary was discarded after changing
341 // memory limit. 329 // memory limit.
342 TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedAmount) { 330 TEST_P(DiscardableMemoryManagerPermutationTest, LRUDiscardedAmount) {
343 SetBytesToKeepUnderModeratePressure(2048);
344 SetMemoryLimit(4096); 331 SetMemoryLimit(4096);
345 332
346 RegisterAndUseAllocations(); 333 RegisterAndUseAllocations();
347 334
348 SetMemoryLimit(2048); 335 SetMemoryLimit(2048);
349 336
350 EXPECT_EQ(LOCK_STATUS_SUCCESS, Lock(allocation(2))); 337 EXPECT_EQ(LOCK_STATUS_SUCCESS, Lock(allocation(2)));
351 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1))); 338 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(1)));
352 // 0 should still be locked. 339 // 0 should still be locked.
353 EXPECT_TRUE(allocation(0)->is_locked()); 340 EXPECT_TRUE(allocation(0)->is_locked());
354 341
355 UnlockAndUnregisterAllocations(); 342 UnlockAndUnregisterAllocations();
356 } 343 }
357 344
358 TEST_P(DiscardableMemoryManagerPermutationTest, PurgeFreesAllUnlocked) { 345 TEST_P(DiscardableMemoryManagerPermutationTest, PurgeFreesAllUnlocked) {
359 RegisterAndUseAllocations(); 346 RegisterAndUseAllocations();
360 347
361 MemoryPressureListener::NotifyMemoryPressure( 348 PurgeAll();
362 MemoryPressureListener::MEMORY_PRESSURE_CRITICAL);
363 RunLoop().RunUntilIdle();
364 349
365 for (int i = 0; i < 3; ++i) { 350 for (int i = 0; i < 3; ++i) {
366 if (i == 0) 351 if (i == 0)
367 EXPECT_TRUE(allocation(i)->is_locked()); 352 EXPECT_TRUE(allocation(i)->is_locked());
368 else 353 else
369 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(i))); 354 EXPECT_EQ(LOCK_STATUS_PURGED, Lock(allocation(i)));
370 } 355 }
371 356
372 UnlockAndUnregisterAllocations(); 357 UnlockAndUnregisterAllocations();
373 } 358 }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 Unretained(this))); 481 Unretained(this)));
497 memory_usage_thread_.message_loop()->PostTask( 482 memory_usage_thread_.message_loop()->PostTask(
498 FROM_HERE, 483 FROM_HERE,
499 Bind(&ThreadedDiscardableMemoryManagerTest::SignalHelper, 484 Bind(&ThreadedDiscardableMemoryManagerTest::SignalHelper,
500 Unretained(this))); 485 Unretained(this)));
501 thread_sync_.Wait(); 486 thread_sync_.Wait();
502 } 487 }
503 488
504 } // namespace 489 } // namespace
505 } // namespace base 490 } // namespace base
OLDNEW
« no previous file with comments | « base/memory/discardable_memory_manager.cc ('k') | base/memory/discardable_memory_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698