| 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 |