OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/basictypes.h" | 5 #include "base/basictypes.h" |
6 #include "base/memory/scoped_ptr.h" | 6 #include "base/memory/scoped_ptr.h" |
7 #include "base/memory/shared_memory.h" | 7 #include "base/memory/shared_memory.h" |
8 #include "base/process/kill.h" | 8 #include "base/process/kill.h" |
9 #include "base/rand_util.h" | 9 #include "base/rand_util.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 void ThreadMain() override { | 58 void ThreadMain() override { |
59 #if defined(OS_MACOSX) | 59 #if defined(OS_MACOSX) |
60 mac::ScopedNSAutoreleasePool pool; | 60 mac::ScopedNSAutoreleasePool pool; |
61 #endif | 61 #endif |
62 const uint32 kDataSize = 1024; | 62 const uint32 kDataSize = 1024; |
63 SharedMemory memory; | 63 SharedMemory memory; |
64 bool rv = memory.CreateNamedDeprecated(s_test_name_, true, kDataSize); | 64 bool rv = memory.CreateNamedDeprecated(s_test_name_, true, kDataSize); |
65 EXPECT_TRUE(rv); | 65 EXPECT_TRUE(rv); |
66 rv = memory.Map(kDataSize); | 66 rv = memory.Map(kDataSize); |
67 EXPECT_TRUE(rv); | 67 EXPECT_TRUE(rv); |
68 int *ptr = static_cast<int*>(memory.memory()) + id_; | 68 int* ptr = static_cast<int*>(memory.memory()) + id_; |
69 EXPECT_EQ(0, *ptr); | 69 EXPECT_EQ(0, *ptr); |
70 | 70 |
71 for (int idx = 0; idx < 100; idx++) { | 71 for (int idx = 0; idx < 100; idx++) { |
72 *ptr = idx; | 72 *ptr = idx; |
73 PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); | 73 PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); |
74 EXPECT_EQ(*ptr, idx); | 74 EXPECT_EQ(*ptr, idx); |
75 } | 75 } |
76 // Reset back to 0 for the next test that uses the same name. | 76 // Reset back to 0 for the next test that uses the same name. |
77 *ptr = 0; | 77 *ptr = 0; |
78 | 78 |
79 memory.Close(); | 79 memory.Close(); |
80 } | 80 } |
81 | 81 |
82 private: | 82 private: |
83 int16 id_; | 83 int16 id_; |
84 | 84 |
85 static const char* const s_test_name_; | 85 static const char s_test_name_[]; |
86 | 86 |
87 DISALLOW_COPY_AND_ASSIGN(MultipleThreadMain); | 87 DISALLOW_COPY_AND_ASSIGN(MultipleThreadMain); |
88 }; | 88 }; |
89 | 89 |
90 const char* const MultipleThreadMain::s_test_name_ = | 90 const char MultipleThreadMain::s_test_name_[] = |
91 "SharedMemoryOpenThreadTest"; | 91 "SharedMemoryOpenThreadTest"; |
92 | 92 |
93 // TODO(port): | 93 // TODO(port): |
94 // This test requires the ability to pass file descriptors between processes. | 94 // This test requires the ability to pass file descriptors between processes. |
95 // We haven't done that yet in Chrome for POSIX. | 95 // We haven't done that yet in Chrome for POSIX. |
96 #if defined(OS_WIN) | 96 #if defined(OS_WIN) |
97 // Each thread will open the shared memory. Each thread will take the memory, | 97 // Each thread will open the shared memory. Each thread will take the memory, |
98 // and keep changing it while trying to lock it, with some small pauses in | 98 // and keep changing it while trying to lock it, with some small pauses in |
99 // between. Verify that each thread's value in the shared memory is always | 99 // between. Verify that each thread's value in the shared memory is always |
100 // correct. | 100 // correct. |
101 class MultipleLockThread : public PlatformThread::Delegate { | 101 class MultipleLockThread : public PlatformThread::Delegate { |
102 public: | 102 public: |
103 explicit MultipleLockThread(int id) : id_(id) {} | 103 explicit MultipleLockThread(int id) : id_(id) {} |
104 virtual ~MultipleLockThread() {} | 104 virtual ~MultipleLockThread() {} |
105 | 105 |
106 // PlatformThread::Delegate interface. | 106 // PlatformThread::Delegate interface. |
107 virtual void ThreadMain() override { | 107 void ThreadMain() override { |
108 const uint32 kDataSize = sizeof(int); | 108 const uint32 kDataSize = sizeof(int); |
109 SharedMemoryHandle handle = NULL; | 109 SharedMemoryHandle handle = NULL; |
110 { | 110 { |
111 SharedMemory memory1; | 111 SharedMemory memory1; |
112 EXPECT_TRUE(memory1.CreateNamedDeprecated( | 112 EXPECT_TRUE(memory1.CreateNamedDeprecated( |
113 "SharedMemoryMultipleLockThreadTest", true, kDataSize)); | 113 "SharedMemoryMultipleLockThreadTest", true, kDataSize)); |
114 EXPECT_TRUE(memory1.ShareToProcess(GetCurrentProcess(), &handle)); | 114 EXPECT_TRUE(memory1.ShareToProcess(GetCurrentProcess(), &handle)); |
115 // TODO(paulg): Implement this once we have a posix version of | 115 // TODO(paulg): Implement this once we have a posix version of |
116 // SharedMemory::ShareToProcess. | 116 // SharedMemory::ShareToProcess. |
117 EXPECT_TRUE(true); | 117 EXPECT_TRUE(true); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 // Make sure we don't segfault. (it actually happened!) | 172 // Make sure we don't segfault. (it actually happened!) |
173 ASSERT_NE(memory1.memory(), static_cast<void*>(NULL)); | 173 ASSERT_NE(memory1.memory(), static_cast<void*>(NULL)); |
174 ASSERT_NE(memory2.memory(), static_cast<void*>(NULL)); | 174 ASSERT_NE(memory2.memory(), static_cast<void*>(NULL)); |
175 | 175 |
176 // Write data to the first memory segment, verify contents of second. | 176 // Write data to the first memory segment, verify contents of second. |
177 memset(memory1.memory(), '1', kDataSize); | 177 memset(memory1.memory(), '1', kDataSize); |
178 EXPECT_EQ(memcmp(memory1.memory(), memory2.memory(), kDataSize), 0); | 178 EXPECT_EQ(memcmp(memory1.memory(), memory2.memory(), kDataSize), 0); |
179 | 179 |
180 // Close the first memory segment, and verify the second has the right data. | 180 // Close the first memory segment, and verify the second has the right data. |
181 memory1.Close(); | 181 memory1.Close(); |
182 char *start_ptr = static_cast<char *>(memory2.memory()); | 182 char* start_ptr = static_cast<char*>(memory2.memory()); |
183 char *end_ptr = start_ptr + kDataSize; | 183 char* end_ptr = start_ptr + kDataSize; |
184 for (char* ptr = start_ptr; ptr < end_ptr; ptr++) | 184 for (char* ptr = start_ptr; ptr < end_ptr; ptr++) |
185 EXPECT_EQ(*ptr, '1'); | 185 EXPECT_EQ(*ptr, '1'); |
186 | 186 |
187 // Close the second memory segment. | 187 // Close the second memory segment. |
188 memory2.Close(); | 188 memory2.Close(); |
189 | 189 |
190 rv = memory1.Delete(test_name); | 190 rv = memory1.Delete(test_name); |
191 EXPECT_TRUE(rv); | 191 EXPECT_TRUE(rv); |
192 rv = memory2.Delete(test_name); | 192 rv = memory2.Delete(test_name); |
193 EXPECT_TRUE(rv); | 193 EXPECT_TRUE(rv); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 EXPECT_TRUE(rv); | 239 EXPECT_TRUE(rv); |
240 | 240 |
241 // The mapped memory2 must be at least the size of the original. | 241 // The mapped memory2 must be at least the size of the original. |
242 EXPECT_GE(memory2.mapped_size(), kDataSize); | 242 EXPECT_GE(memory2.mapped_size(), kDataSize); |
243 | 243 |
244 // The mapped memory2 shouldn't exceed rounding for allocation granularity. | 244 // The mapped memory2 shouldn't exceed rounding for allocation granularity. |
245 EXPECT_LT(memory2.mapped_size(), | 245 EXPECT_LT(memory2.mapped_size(), |
246 kDataSize2 + base::SysInfo::VMAllocationGranularity()); | 246 kDataSize2 + base::SysInfo::VMAllocationGranularity()); |
247 | 247 |
248 // Verify that opening memory2 didn't truncate or delete memory 1. | 248 // Verify that opening memory2 didn't truncate or delete memory 1. |
249 char *start_ptr = static_cast<char *>(memory2.memory()); | 249 char* start_ptr = static_cast<char*>(memory2.memory()); |
250 char *end_ptr = start_ptr + kDataSize; | 250 char* end_ptr = start_ptr + kDataSize; |
251 for (char* ptr = start_ptr; ptr < end_ptr; ptr++) { | 251 for (char* ptr = start_ptr; ptr < end_ptr; ptr++) { |
252 EXPECT_EQ(*ptr, 'G'); | 252 EXPECT_EQ(*ptr, 'G'); |
253 } | 253 } |
254 | 254 |
255 memory1.Close(); | 255 memory1.Close(); |
256 memory2.Close(); | 256 memory2.Close(); |
257 | 257 |
258 rv = memory1.Delete(test_name); | 258 rv = memory1.Delete(test_name); |
259 EXPECT_TRUE(rv); | 259 EXPECT_TRUE(rv); |
260 } | 260 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 const uint32 kDataSize = 8192; | 358 const uint32 kDataSize = 8192; |
359 | 359 |
360 scoped_ptr<SharedMemory[]> memories(new SharedMemory[count]); | 360 scoped_ptr<SharedMemory[]> memories(new SharedMemory[count]); |
361 scoped_ptr<int*[]> pointers(new int*[count]); | 361 scoped_ptr<int*[]> pointers(new int*[count]); |
362 ASSERT_TRUE(memories.get()); | 362 ASSERT_TRUE(memories.get()); |
363 ASSERT_TRUE(pointers.get()); | 363 ASSERT_TRUE(pointers.get()); |
364 | 364 |
365 for (i = 0; i < count; i++) { | 365 for (i = 0; i < count; i++) { |
366 rv = memories[i].CreateAndMapAnonymous(kDataSize); | 366 rv = memories[i].CreateAndMapAnonymous(kDataSize); |
367 EXPECT_TRUE(rv); | 367 EXPECT_TRUE(rv); |
368 int *ptr = static_cast<int*>(memories[i].memory()); | 368 int* ptr = static_cast<int*>(memories[i].memory()); |
369 EXPECT_TRUE(ptr); | 369 EXPECT_TRUE(ptr); |
370 pointers[i] = ptr; | 370 pointers[i] = ptr; |
371 } | 371 } |
372 | 372 |
373 for (i = 0; i < count; i++) { | 373 for (i = 0; i < count; i++) { |
374 // zero out the first int in each except for i; for that one, make it 100. | 374 // zero out the first int in each except for i; for that one, make it 100. |
375 for (j = 0; j < count; j++) { | 375 for (j = 0; j < count; j++) { |
376 if (i == j) | 376 if (i == j) |
377 pointers[j][0] = 100; | 377 pointers[j][0] = 100; |
378 else | 378 else |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 shared_memory.memory()) & (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1)); | 646 shared_memory.memory()) & (SharedMemory::MAP_MINIMUM_ALIGNMENT - 1)); |
647 shared_memory.Close(); | 647 shared_memory.Close(); |
648 } | 648 } |
649 | 649 |
650 #if !defined(OS_IOS) // iOS does not allow multiple processes. | 650 #if !defined(OS_IOS) // iOS does not allow multiple processes. |
651 | 651 |
652 // On POSIX it is especially important we test shmem across processes, | 652 // On POSIX it is especially important we test shmem across processes, |
653 // not just across threads. But the test is enabled on all platforms. | 653 // not just across threads. But the test is enabled on all platforms. |
654 class SharedMemoryProcessTest : public MultiProcessTest { | 654 class SharedMemoryProcessTest : public MultiProcessTest { |
655 public: | 655 public: |
656 | |
657 static void CleanUp() { | 656 static void CleanUp() { |
658 SharedMemory memory; | 657 SharedMemory memory; |
659 memory.Delete(s_test_name_); | 658 memory.Delete(s_test_name_); |
660 } | 659 } |
661 | 660 |
662 static int TaskTestMain() { | 661 static int TaskTestMain() { |
663 int errors = 0; | 662 int errors = 0; |
664 #if defined(OS_MACOSX) | 663 #if defined(OS_MACOSX) |
665 mac::ScopedNSAutoreleasePool pool; | 664 mac::ScopedNSAutoreleasePool pool; |
666 #endif | 665 #endif |
667 const uint32 kDataSize = 1024; | 666 const uint32 kDataSize = 1024; |
668 SharedMemory memory; | 667 SharedMemory memory; |
669 bool rv = memory.CreateNamedDeprecated(s_test_name_, true, kDataSize); | 668 bool rv = memory.CreateNamedDeprecated(s_test_name_, true, kDataSize); |
670 EXPECT_TRUE(rv); | 669 EXPECT_TRUE(rv); |
671 if (rv != true) | 670 if (rv != true) |
672 errors++; | 671 errors++; |
673 rv = memory.Map(kDataSize); | 672 rv = memory.Map(kDataSize); |
674 EXPECT_TRUE(rv); | 673 EXPECT_TRUE(rv); |
675 if (rv != true) | 674 if (rv != true) |
676 errors++; | 675 errors++; |
677 int *ptr = static_cast<int*>(memory.memory()); | 676 int* ptr = static_cast<int*>(memory.memory()); |
678 | 677 |
679 for (int idx = 0; idx < 20; idx++) { | 678 for (int idx = 0; idx < 20; idx++) { |
680 memory.LockDeprecated(); | 679 memory.LockDeprecated(); |
681 int i = (1 << 16) + idx; | 680 int i = (1 << 16) + idx; |
682 *ptr = i; | 681 *ptr = i; |
683 PlatformThread::Sleep(TimeDelta::FromMilliseconds(10)); | 682 PlatformThread::Sleep(TimeDelta::FromMilliseconds(10)); |
684 if (*ptr != i) | 683 if (*ptr != i) |
685 errors++; | 684 errors++; |
686 memory.UnlockDeprecated(); | 685 memory.UnlockDeprecated(); |
687 } | 686 } |
688 | 687 |
689 memory.Close(); | 688 memory.Close(); |
690 return errors; | 689 return errors; |
691 } | 690 } |
692 | 691 |
693 private: | 692 private: |
694 static const char* const s_test_name_; | 693 static const char s_test_name_[]; |
695 }; | 694 }; |
696 | 695 |
697 const char* const SharedMemoryProcessTest::s_test_name_ = "MPMem"; | 696 const char SharedMemoryProcessTest::s_test_name_[] = "MPMem"; |
698 | 697 |
699 TEST_F(SharedMemoryProcessTest, Tasks) { | 698 TEST_F(SharedMemoryProcessTest, Tasks) { |
700 SharedMemoryProcessTest::CleanUp(); | 699 SharedMemoryProcessTest::CleanUp(); |
701 | 700 |
702 Process processes[kNumTasks]; | 701 Process processes[kNumTasks]; |
703 for (int index = 0; index < kNumTasks; ++index) { | 702 for (int index = 0; index < kNumTasks; ++index) { |
704 processes[index] = SpawnChild("SharedMemoryTestMain"); | 703 processes[index] = SpawnChild("SharedMemoryTestMain"); |
705 ASSERT_TRUE(processes[index].IsValid()); | 704 ASSERT_TRUE(processes[index].IsValid()); |
706 } | 705 } |
707 | 706 |
708 int exit_code = 0; | 707 int exit_code = 0; |
709 for (int index = 0; index < kNumTasks; ++index) { | 708 for (int index = 0; index < kNumTasks; ++index) { |
710 EXPECT_TRUE(processes[index].WaitForExit(&exit_code)); | 709 EXPECT_TRUE(processes[index].WaitForExit(&exit_code)); |
711 EXPECT_EQ(0, exit_code); | 710 EXPECT_EQ(0, exit_code); |
712 } | 711 } |
713 | 712 |
714 SharedMemoryProcessTest::CleanUp(); | 713 SharedMemoryProcessTest::CleanUp(); |
715 } | 714 } |
716 | 715 |
717 MULTIPROCESS_TEST_MAIN(SharedMemoryTestMain) { | 716 MULTIPROCESS_TEST_MAIN(SharedMemoryTestMain) { |
718 return SharedMemoryProcessTest::TaskTestMain(); | 717 return SharedMemoryProcessTest::TaskTestMain(); |
719 } | 718 } |
720 | 719 |
721 #endif // !OS_IOS | 720 #endif // !OS_IOS |
722 | 721 |
723 } // namespace base | 722 } // namespace base |
OLD | NEW |