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 <stdint.h> | 5 #include <stdint.h> |
6 | 6 |
7 #include "base/memory/discardable_shared_memory.h" | 7 #include "base/memory/discardable_shared_memory.h" |
8 #include "base/process/process_metrics.h" | 8 #include "base/process/process_metrics.h" |
9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
10 | 10 |
(...skipping 26 matching lines...) Expand all Loading... |
37 EXPECT_TRUE(memory.IsMemoryLocked()); | 37 EXPECT_TRUE(memory.IsMemoryLocked()); |
38 } | 38 } |
39 | 39 |
40 TEST(DiscardableSharedMemoryTest, CreateFromHandle) { | 40 TEST(DiscardableSharedMemoryTest, CreateFromHandle) { |
41 const uint32_t kDataSize = 1024; | 41 const uint32_t kDataSize = 1024; |
42 | 42 |
43 TestDiscardableSharedMemory memory1; | 43 TestDiscardableSharedMemory memory1; |
44 bool rv = memory1.CreateAndMap(kDataSize); | 44 bool rv = memory1.CreateAndMap(kDataSize); |
45 ASSERT_TRUE(rv); | 45 ASSERT_TRUE(rv); |
46 | 46 |
47 SharedMemoryHandle shared_handle; | 47 SharedMemoryHandle shared_handle = memory1.handle().Duplicate(); |
48 ASSERT_TRUE( | 48 ASSERT_TRUE(shared_handle.IsValid()); |
49 memory1.ShareToProcess(GetCurrentProcessHandle(), &shared_handle)); | |
50 ASSERT_TRUE(SharedMemory::IsHandleValid(shared_handle)); | |
51 | 49 |
52 TestDiscardableSharedMemory memory2(shared_handle); | 50 TestDiscardableSharedMemory memory2(shared_handle); |
53 rv = memory2.Map(kDataSize); | 51 rv = memory2.Map(kDataSize); |
54 ASSERT_TRUE(rv); | 52 ASSERT_TRUE(rv); |
55 EXPECT_TRUE(memory2.IsMemoryLocked()); | 53 EXPECT_TRUE(memory2.IsMemoryLocked()); |
56 } | 54 } |
57 | 55 |
58 TEST(DiscardableSharedMemoryTest, LockAndUnlock) { | 56 TEST(DiscardableSharedMemoryTest, LockAndUnlock) { |
59 const uint32_t kDataSize = 1024; | 57 const uint32_t kDataSize = 1024; |
60 | 58 |
(...skipping 10 matching lines...) Expand all Loading... |
71 DiscardableSharedMemory::LockResult lock_rv = memory1.Lock(0, 0); | 69 DiscardableSharedMemory::LockResult lock_rv = memory1.Lock(0, 0); |
72 EXPECT_EQ(DiscardableSharedMemory::SUCCESS, lock_rv); | 70 EXPECT_EQ(DiscardableSharedMemory::SUCCESS, lock_rv); |
73 memory1.SetNow(Time::FromDoubleT(2)); | 71 memory1.SetNow(Time::FromDoubleT(2)); |
74 memory1.Unlock(0, 0); | 72 memory1.Unlock(0, 0); |
75 | 73 |
76 // Lock again before duplicating and passing ownership to new instance. | 74 // Lock again before duplicating and passing ownership to new instance. |
77 lock_rv = memory1.Lock(0, 0); | 75 lock_rv = memory1.Lock(0, 0); |
78 EXPECT_EQ(DiscardableSharedMemory::SUCCESS, lock_rv); | 76 EXPECT_EQ(DiscardableSharedMemory::SUCCESS, lock_rv); |
79 EXPECT_TRUE(memory1.IsMemoryLocked()); | 77 EXPECT_TRUE(memory1.IsMemoryLocked()); |
80 | 78 |
81 SharedMemoryHandle shared_handle; | 79 SharedMemoryHandle shared_handle = memory1.handle().Duplicate(); |
82 ASSERT_TRUE( | 80 ASSERT_TRUE(shared_handle.IsValid()); |
83 memory1.ShareToProcess(GetCurrentProcessHandle(), &shared_handle)); | |
84 ASSERT_TRUE(SharedMemory::IsHandleValid(shared_handle)); | |
85 | 81 |
86 TestDiscardableSharedMemory memory2(shared_handle); | 82 TestDiscardableSharedMemory memory2(shared_handle); |
87 rv = memory2.Map(kDataSize); | 83 rv = memory2.Map(kDataSize); |
88 ASSERT_TRUE(rv); | 84 ASSERT_TRUE(rv); |
89 | 85 |
90 // Unlock second instance. | 86 // Unlock second instance. |
91 memory2.SetNow(Time::FromDoubleT(3)); | 87 memory2.SetNow(Time::FromDoubleT(3)); |
92 memory2.Unlock(0, 0); | 88 memory2.Unlock(0, 0); |
93 | 89 |
94 // Both memory instances should be unlocked now. | 90 // Both memory instances should be unlocked now. |
(...skipping 14 matching lines...) Expand all Loading... |
109 memory1.Unlock(0, 0); | 105 memory1.Unlock(0, 0); |
110 } | 106 } |
111 | 107 |
112 TEST(DiscardableSharedMemoryTest, Purge) { | 108 TEST(DiscardableSharedMemoryTest, Purge) { |
113 const uint32_t kDataSize = 1024; | 109 const uint32_t kDataSize = 1024; |
114 | 110 |
115 TestDiscardableSharedMemory memory1; | 111 TestDiscardableSharedMemory memory1; |
116 bool rv = memory1.CreateAndMap(kDataSize); | 112 bool rv = memory1.CreateAndMap(kDataSize); |
117 ASSERT_TRUE(rv); | 113 ASSERT_TRUE(rv); |
118 | 114 |
119 SharedMemoryHandle shared_handle; | 115 SharedMemoryHandle shared_handle = memory1.handle().Duplicate(); |
120 ASSERT_TRUE( | 116 ASSERT_TRUE(shared_handle.IsValid()); |
121 memory1.ShareToProcess(GetCurrentProcessHandle(), &shared_handle)); | |
122 ASSERT_TRUE(SharedMemory::IsHandleValid(shared_handle)); | |
123 | 117 |
124 TestDiscardableSharedMemory memory2(shared_handle); | 118 TestDiscardableSharedMemory memory2(shared_handle); |
125 rv = memory2.Map(kDataSize); | 119 rv = memory2.Map(kDataSize); |
126 ASSERT_TRUE(rv); | 120 ASSERT_TRUE(rv); |
127 | 121 |
128 // This should fail as memory is locked. | 122 // This should fail as memory is locked. |
129 rv = memory1.Purge(Time::FromDoubleT(1)); | 123 rv = memory1.Purge(Time::FromDoubleT(1)); |
130 EXPECT_FALSE(rv); | 124 EXPECT_FALSE(rv); |
131 | 125 |
132 memory2.SetNow(Time::FromDoubleT(2)); | 126 memory2.SetNow(Time::FromDoubleT(2)); |
(...skipping 18 matching lines...) Expand all Loading... |
151 ASSERT_FALSE(memory2.IsMemoryResident()); | 145 ASSERT_FALSE(memory2.IsMemoryResident()); |
152 } | 146 } |
153 | 147 |
154 TEST(DiscardableSharedMemoryTest, LastUsed) { | 148 TEST(DiscardableSharedMemoryTest, LastUsed) { |
155 const uint32_t kDataSize = 1024; | 149 const uint32_t kDataSize = 1024; |
156 | 150 |
157 TestDiscardableSharedMemory memory1; | 151 TestDiscardableSharedMemory memory1; |
158 bool rv = memory1.CreateAndMap(kDataSize); | 152 bool rv = memory1.CreateAndMap(kDataSize); |
159 ASSERT_TRUE(rv); | 153 ASSERT_TRUE(rv); |
160 | 154 |
161 SharedMemoryHandle shared_handle; | 155 SharedMemoryHandle shared_handle = memory1.handle().Duplicate(); |
162 ASSERT_TRUE( | 156 ASSERT_TRUE(shared_handle.IsValid()); |
163 memory1.ShareToProcess(GetCurrentProcessHandle(), &shared_handle)); | |
164 ASSERT_TRUE(SharedMemory::IsHandleValid(shared_handle)); | |
165 | 157 |
166 TestDiscardableSharedMemory memory2(shared_handle); | 158 TestDiscardableSharedMemory memory2(shared_handle); |
167 rv = memory2.Map(kDataSize); | 159 rv = memory2.Map(kDataSize); |
168 ASSERT_TRUE(rv); | 160 ASSERT_TRUE(rv); |
169 | 161 |
170 memory2.SetNow(Time::FromDoubleT(1)); | 162 memory2.SetNow(Time::FromDoubleT(1)); |
171 memory2.Unlock(0, 0); | 163 memory2.Unlock(0, 0); |
172 | 164 |
173 EXPECT_EQ(memory2.last_known_usage(), Time::FromDoubleT(1)); | 165 EXPECT_EQ(memory2.last_known_usage(), Time::FromDoubleT(1)); |
174 | 166 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 EXPECT_TRUE(rv); | 211 EXPECT_TRUE(rv); |
220 } | 212 } |
221 | 213 |
222 TEST(DiscardableSharedMemoryTest, LockShouldAlwaysFailAfterSuccessfulPurge) { | 214 TEST(DiscardableSharedMemoryTest, LockShouldAlwaysFailAfterSuccessfulPurge) { |
223 const uint32_t kDataSize = 1024; | 215 const uint32_t kDataSize = 1024; |
224 | 216 |
225 TestDiscardableSharedMemory memory1; | 217 TestDiscardableSharedMemory memory1; |
226 bool rv = memory1.CreateAndMap(kDataSize); | 218 bool rv = memory1.CreateAndMap(kDataSize); |
227 ASSERT_TRUE(rv); | 219 ASSERT_TRUE(rv); |
228 | 220 |
229 SharedMemoryHandle shared_handle; | 221 SharedMemoryHandle shared_handle = memory1.handle().Duplicate(); |
230 ASSERT_TRUE( | 222 ASSERT_TRUE(shared_handle.IsValid()); |
231 memory1.ShareToProcess(GetCurrentProcessHandle(), &shared_handle)); | |
232 ASSERT_TRUE(SharedMemory::IsHandleValid(shared_handle)); | |
233 | 223 |
234 TestDiscardableSharedMemory memory2(shared_handle); | 224 TestDiscardableSharedMemory memory2(shared_handle); |
235 rv = memory2.Map(kDataSize); | 225 rv = memory2.Map(kDataSize); |
236 ASSERT_TRUE(rv); | 226 ASSERT_TRUE(rv); |
237 | 227 |
238 memory2.SetNow(Time::FromDoubleT(1)); | 228 memory2.SetNow(Time::FromDoubleT(1)); |
239 memory2.Unlock(0, 0); | 229 memory2.Unlock(0, 0); |
240 | 230 |
241 rv = memory2.Purge(Time::FromDoubleT(2)); | 231 rv = memory2.Purge(Time::FromDoubleT(2)); |
242 EXPECT_TRUE(rv); | 232 EXPECT_TRUE(rv); |
243 | 233 |
244 // Lock should fail as memory has been purged. | 234 // Lock should fail as memory has been purged. |
245 DiscardableSharedMemory::LockResult lock_rv = memory2.Lock(0, 0); | 235 DiscardableSharedMemory::LockResult lock_rv = memory2.Lock(0, 0); |
246 EXPECT_EQ(DiscardableSharedMemory::FAILED, lock_rv); | 236 EXPECT_EQ(DiscardableSharedMemory::FAILED, lock_rv); |
247 } | 237 } |
248 | 238 |
249 TEST(DiscardableSharedMemoryTest, LockAndUnlockRange) { | 239 TEST(DiscardableSharedMemoryTest, LockAndUnlockRange) { |
250 const uint32_t kDataSize = 32; | 240 const uint32_t kDataSize = 32; |
251 | 241 |
252 uint32_t data_size_in_bytes = kDataSize * base::GetPageSize(); | 242 uint32_t data_size_in_bytes = kDataSize * base::GetPageSize(); |
253 | 243 |
254 TestDiscardableSharedMemory memory1; | 244 TestDiscardableSharedMemory memory1; |
255 bool rv = memory1.CreateAndMap(data_size_in_bytes); | 245 bool rv = memory1.CreateAndMap(data_size_in_bytes); |
256 ASSERT_TRUE(rv); | 246 ASSERT_TRUE(rv); |
257 | 247 |
258 SharedMemoryHandle shared_handle; | 248 SharedMemoryHandle shared_handle = memory1.handle().Duplicate(); |
259 ASSERT_TRUE( | 249 ASSERT_TRUE(shared_handle.IsValid()); |
260 memory1.ShareToProcess(GetCurrentProcessHandle(), &shared_handle)); | |
261 ASSERT_TRUE(SharedMemory::IsHandleValid(shared_handle)); | |
262 | 250 |
263 TestDiscardableSharedMemory memory2(shared_handle); | 251 TestDiscardableSharedMemory memory2(shared_handle); |
264 rv = memory2.Map(data_size_in_bytes); | 252 rv = memory2.Map(data_size_in_bytes); |
265 ASSERT_TRUE(rv); | 253 ASSERT_TRUE(rv); |
266 | 254 |
267 // Unlock first page. | 255 // Unlock first page. |
268 memory2.SetNow(Time::FromDoubleT(1)); | 256 memory2.SetNow(Time::FromDoubleT(1)); |
269 memory2.Unlock(0, base::GetPageSize()); | 257 memory2.Unlock(0, base::GetPageSize()); |
270 | 258 |
271 rv = memory1.Purge(Time::FromDoubleT(2)); | 259 rv = memory1.Purge(Time::FromDoubleT(2)); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 // when DISCARDABLE_SHARED_MEMORY_ZERO_FILL_ON_DEMAND_PAGES_AFTER_PURGE is | 355 // when DISCARDABLE_SHARED_MEMORY_ZERO_FILL_ON_DEMAND_PAGES_AFTER_PURGE is |
368 // defined and MADV_REMOVE is supported. | 356 // defined and MADV_REMOVE is supported. |
369 #if defined(DISCARDABLE_SHARED_MEMORY_ZERO_FILL_ON_DEMAND_PAGES_AFTER_PURGE) | 357 #if defined(DISCARDABLE_SHARED_MEMORY_ZERO_FILL_ON_DEMAND_PAGES_AFTER_PURGE) |
370 TEST(DiscardableSharedMemoryTest, ZeroFilledPagesAfterPurge) { | 358 TEST(DiscardableSharedMemoryTest, ZeroFilledPagesAfterPurge) { |
371 const uint32_t kDataSize = 1024; | 359 const uint32_t kDataSize = 1024; |
372 | 360 |
373 TestDiscardableSharedMemory memory1; | 361 TestDiscardableSharedMemory memory1; |
374 bool rv = memory1.CreateAndMap(kDataSize); | 362 bool rv = memory1.CreateAndMap(kDataSize); |
375 ASSERT_TRUE(rv); | 363 ASSERT_TRUE(rv); |
376 | 364 |
377 SharedMemoryHandle shared_handle; | 365 SharedMemoryHandle shared_handle = memory1.handle().Duplicate(); |
378 ASSERT_TRUE( | 366 ASSERT_TRUE(shared_handle.IsValid()); |
379 memory1.ShareToProcess(GetCurrentProcessHandle(), &shared_handle)); | |
380 ASSERT_TRUE(SharedMemory::IsHandleValid(shared_handle)); | |
381 | 367 |
382 TestDiscardableSharedMemory memory2(shared_handle); | 368 TestDiscardableSharedMemory memory2(shared_handle); |
383 rv = memory2.Map(kDataSize); | 369 rv = memory2.Map(kDataSize); |
384 ASSERT_TRUE(rv); | 370 ASSERT_TRUE(rv); |
385 | 371 |
386 // Initialize all memory to '0xaa'. | 372 // Initialize all memory to '0xaa'. |
387 memset(memory2.memory(), 0xaa, kDataSize); | 373 memset(memory2.memory(), 0xaa, kDataSize); |
388 | 374 |
389 // Unlock memory. | 375 // Unlock memory. |
390 memory2.SetNow(Time::FromDoubleT(1)); | 376 memory2.SetNow(Time::FromDoubleT(1)); |
391 memory2.Unlock(0, 0); | 377 memory2.Unlock(0, 0); |
392 EXPECT_FALSE(memory1.IsMemoryLocked()); | 378 EXPECT_FALSE(memory1.IsMemoryLocked()); |
393 | 379 |
394 // Memory is unlocked, but our usage timestamp is incorrect. | 380 // Memory is unlocked, but our usage timestamp is incorrect. |
395 rv = memory1.Purge(Time::FromDoubleT(2)); | 381 rv = memory1.Purge(Time::FromDoubleT(2)); |
396 EXPECT_FALSE(rv); | 382 EXPECT_FALSE(rv); |
397 rv = memory1.Purge(Time::FromDoubleT(3)); | 383 rv = memory1.Purge(Time::FromDoubleT(3)); |
398 EXPECT_TRUE(rv); | 384 EXPECT_TRUE(rv); |
399 | 385 |
400 // Check that reading memory after it has been purged is returning | 386 // Check that reading memory after it has been purged is returning |
401 // zero-filled pages. | 387 // zero-filled pages. |
402 uint8_t expected_data[kDataSize] = {}; | 388 uint8_t expected_data[kDataSize] = {}; |
403 EXPECT_EQ(memcmp(memory2.memory(), expected_data, kDataSize), 0); | 389 EXPECT_EQ(memcmp(memory2.memory(), expected_data, kDataSize), 0); |
404 } | 390 } |
405 #endif | 391 #endif |
406 | 392 |
407 } // namespace | 393 } // namespace |
408 } // namespace base | 394 } // namespace base |
OLD | NEW |