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

Side by Side Diff: base/shared_memory_unittest.cc

Issue 1922: First pass of porting the shared memory unittest. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years, 3 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/base.xcodeproj/project.pbxproj ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 <process.h> // _beginthreadex 5 #include "base/basictypes.h"
6 #include "base/platform_thread.h"
6 #include "base/shared_memory.h" 7 #include "base/shared_memory.h"
7 #include "testing/gtest/include/gtest/gtest.h" 8 #include "testing/gtest/include/gtest/gtest.h"
8 9
10 static const int kNumThreads = 5;
9 11
10 namespace { 12 namespace {
11 13
12 class SharedMemoryTest : public testing::Test { 14 class SharedMemoryTest : public testing::Test {
13 }; 15 };
14 16
15 unsigned __stdcall MultipleThreadMain(void* param) { 17 // Each thread will open the shared memory. Each thread will take a different 4
16 // Each thread will open the shared memory. Each thread will take 18 // byte int pointer, and keep changing it, with some small pauses in between.
17 // a different 4 byte int pointer, and keep changing it, with some 19 // Verify that each thread's value in the shared memory is always correct.
18 // small pauses in between. Verify that each thread's value in the 20 class MultipleThreadMain : public PlatformThread::Delegate {
19 // shared memory is always correct. 21 public:
20 const int kDataSize = 1024; 22 explicit MultipleThreadMain(int16 id) : id_(id) {}
21 std::wstring test_name = L"SharedMemoryOpenThreadTest"; 23 ~MultipleThreadMain() {}
22 int16 id = reinterpret_cast<int16>(param); 24
23 SharedMemory memory; 25 // PlatformThread::Delegate interface.
24 bool rv = memory.Create(test_name, false, true, kDataSize); 26 void ThreadMain() {
25 EXPECT_TRUE(rv); 27 const int kDataSize = 1024;
26 rv = memory.Map(kDataSize); 28 std::wstring test_name = L"SharedMemoryOpenThreadTest";
27 EXPECT_TRUE(rv); 29 SharedMemory memory;
28 int *ptr = static_cast<int*>(memory.memory()) + id; 30 bool rv = memory.Create(test_name, false, true, kDataSize);
29 EXPECT_EQ(*ptr, 0); 31 EXPECT_TRUE(rv);
30 for (int idx = 0; idx < 100; idx++) { 32 rv = memory.Map(kDataSize);
31 *ptr = idx; 33 EXPECT_TRUE(rv);
32 Sleep(1); // short wait 34 int *ptr = static_cast<int*>(memory.memory()) + id_;
33 EXPECT_EQ(*ptr, idx); 35 EXPECT_EQ(*ptr, 0);
36
37 for (int idx = 0; idx < 100; idx++) {
38 *ptr = idx;
39 PlatformThread::Sleep(1); // Short wait.
40 EXPECT_EQ(*ptr, idx);
41 }
42
43 memory.Close();
34 } 44 }
35 memory.Close();
36 return 0;
37 }
38 45
39 unsigned __stdcall MultipleLockThread(void* param) { 46 private:
40 // Each thread will open the shared memory. Each thread will take 47 int16 id_;
41 // the memory, and keep changing it while trying to lock it, with some 48
42 // small pauses in between. Verify that each thread's value in the 49 DISALLOW_COPY_AND_ASSIGN(MultipleThreadMain);
43 // shared memory is always correct. 50 };
44 const int kDataSize = sizeof(int); 51
45 int id = static_cast<int>(reinterpret_cast<INT_PTR>(param)); 52 #if defined(OS_WIN)
46 SharedMemoryHandle handle = NULL; 53 // Each thread will open the shared memory. Each thread will take the memory,
47 { 54 // and keep changing it while trying to lock it, with some small pauses in
48 SharedMemory memory1; 55 // between. Verify that each thread's value in the shared memory is always
49 EXPECT_TRUE(memory1.Create(L"SharedMemoryMultipleLockThreadTest", false, tru e, 56 // correct.
50 kDataSize)); 57 class MultipleLockThread : public PlatformThread::Delegate {
51 EXPECT_TRUE(memory1.ShareToProcess(GetCurrentProcess(), &handle)); 58 public:
59 explicit MultipleLockThread(int id) : id_(id) {}
60 ~MultipleLockThread() {}
61
62 // PlatformThread::Delegate interface.
63 void ThreadMain() {
64 const int kDataSize = sizeof(int);
65 SharedMemoryHandle handle = NULL;
66 {
67 SharedMemory memory1;
68 EXPECT_TRUE(memory1.Create(L"SharedMemoryMultipleLockThreadTest",
69 false, true, kDataSize));
70 EXPECT_TRUE(memory1.ShareToProcess(GetCurrentProcess(), &handle));
71 // TODO(paulg): Implement this once we have a posix version of
72 // SharedMemory::ShareToProcess.
73 EXPECT_TRUE(true);
74 }
75
76 SharedMemory memory2(handle, false);
77 EXPECT_TRUE(memory2.Map(kDataSize));
78 volatile int* const ptr = static_cast<int*>(memory2.memory());
79
80 for (int idx = 0; idx < 20; idx++) {
81 memory2.Lock();
82 int i = (id_ << 16) + idx;
83 *ptr = i;
84 PlatformThread::Sleep(1); // Short wait.
85 EXPECT_EQ(*ptr, i);
86 memory2.Unlock();
87 }
88
89 memory2.Close();
52 } 90 }
53 SharedMemory memory2(handle, false); 91
54 EXPECT_TRUE(memory2.Map(kDataSize)); 92 private:
55 volatile int* const ptr = static_cast<int*>(memory2.memory()); 93 int id_;
56 for (int idx = 0; idx < 20; idx++) { 94
57 memory2.Lock(); 95 DISALLOW_COPY_AND_ASSIGN(MultipleLockThread);
58 int i = (id << 16) + idx; 96 };
59 *ptr = i; 97 #endif
60 // short wait
61 Sleep(1);
62 EXPECT_EQ(*ptr, i);
63 memory2.Unlock();
64 }
65 memory2.Close();
66 return 0;
67 }
68 98
69 } // namespace 99 } // namespace
70 100
71 TEST(SharedMemoryTest, OpenClose) { 101 TEST(SharedMemoryTest, OpenClose) {
72 const int kDataSize = 1024; 102 const int kDataSize = 1024;
73 std::wstring test_name = L"SharedMemoryOpenCloseTest"; 103 std::wstring test_name = L"SharedMemoryOpenCloseTest";
74 104
75 // Open two handles to a memory segment, confirm that they 105 // Open two handles to a memory segment, confirm that they are mapped
76 // are mapped separately yet point to the same space. 106 // separately yet point to the same space.
77 SharedMemory memory1; 107 SharedMemory memory1;
78 bool rv = memory1.Open(test_name, false); 108 bool rv = memory1.Open(test_name, false);
79 EXPECT_FALSE(rv); 109 EXPECT_FALSE(rv);
80 rv = memory1.Create(test_name, false, false, kDataSize); 110 rv = memory1.Create(test_name, false, false, kDataSize);
81 EXPECT_TRUE(rv); 111 EXPECT_TRUE(rv);
82 rv = memory1.Map(kDataSize); 112 rv = memory1.Map(kDataSize);
83 EXPECT_TRUE(rv); 113 EXPECT_TRUE(rv);
84 SharedMemory memory2; 114 SharedMemory memory2;
85 rv = memory2.Open(test_name, false); 115 rv = memory2.Open(test_name, false);
86 EXPECT_TRUE(rv); 116 EXPECT_TRUE(rv);
87 rv = memory2.Map(kDataSize); 117 rv = memory2.Map(kDataSize);
88 EXPECT_TRUE(rv); 118 EXPECT_TRUE(rv);
89 EXPECT_NE(memory1.memory(), memory2.memory()); // compare the pointers 119 EXPECT_NE(memory1.memory(), memory2.memory()); // Compare the pointers.
90 120
91 121
92 // Write data to the first memory segment, verify contents of second. 122 // Write data to the first memory segment, verify contents of second.
93 memset(memory1.memory(), '1', kDataSize); 123 memset(memory1.memory(), '1', kDataSize);
94 EXPECT_EQ(memcmp(memory1.memory(), memory2.memory(), kDataSize), 0); 124 EXPECT_EQ(memcmp(memory1.memory(), memory2.memory(), kDataSize), 0);
95 125
96 // Close the first memory segment, and verify the 126 // Close the first memory segment, and verify the second has the right data.
97 // second still has the right data.
98 memory1.Close(); 127 memory1.Close();
99 char *start_ptr = static_cast<char *>(memory2.memory()); 128 char *start_ptr = static_cast<char *>(memory2.memory());
100 char *end_ptr = start_ptr + kDataSize; 129 char *end_ptr = start_ptr + kDataSize;
101 for (char* ptr = start_ptr; ptr < end_ptr; ptr++) 130 for (char* ptr = start_ptr; ptr < end_ptr; ptr++)
102 EXPECT_EQ(*ptr, '1'); 131 EXPECT_EQ(*ptr, '1');
103 132
104 // Close the second memory segment 133 // Close the second memory segment.
105 memory2.Close(); 134 memory2.Close();
106 } 135 }
107 136
108 137 #if defined(OS_WIN)
138 // Create a set of 5 threads to each open a shared memory segment and write to
139 // it. Verify that they are always reading/writing consistent data.
109 TEST(SharedMemoryTest, MultipleThreads) { 140 TEST(SharedMemoryTest, MultipleThreads) {
110 // Create a set of 5 threads to each open a shared memory segment 141 PlatformThreadHandle thread_handles[kNumThreads];
111 // and write to it. Verify that they are always reading/writing 142 MultipleThreadMain* thread_delegates[kNumThreads];
112 // consistent data.
113 const int kNumThreads = 5;
114 HANDLE threads[kNumThreads];
115 143
116 // Spawn the threads. 144 // Spawn the threads.
117 for (int16 index = 0; index < kNumThreads; index++) { 145 for (int16 index = 0; index < kNumThreads; index++) {
118 void *argument = reinterpret_cast<void*>(index); 146 PlatformThreadHandle pth;
119 unsigned thread_id; 147 thread_delegates[index] = new MultipleThreadMain(index);
120 threads[index] = reinterpret_cast<HANDLE>( 148 EXPECT_TRUE(PlatformThread::Create(0, thread_delegates[index], &pth));
121 _beginthreadex(NULL, 0, MultipleThreadMain, argument, 0, &thread_id)); 149 thread_handles[index] = pth;
122 EXPECT_NE(threads[index], static_cast<HANDLE>(NULL));
123 } 150 }
124 151
125 // Wait for the threads to finish. 152 // Wait for the threads to finish.
126 for (int index = 0; index < kNumThreads; index++) { 153 for (int index = 0; index < kNumThreads; index++) {
127 DWORD rv = WaitForSingleObject(threads[index], 60*1000); 154 PlatformThread::Join(thread_handles[index]);
128 EXPECT_EQ(rv, WAIT_OBJECT_0); // verify all threads finished 155 delete thread_delegates[index];
129 CloseHandle(threads[index]);
130 } 156 }
131 } 157 }
132 158
133 159 // Create a set of threads to each open a shared memory segment and write to it
160 // with the lock held. Verify that they are always reading/writing consistent
161 // data.
134 TEST(SharedMemoryTest, Lock) { 162 TEST(SharedMemoryTest, Lock) {
135 // Create a set of threads to each open a shared memory segment and write to 163 PlatformThreadHandle thread_handles[kNumThreads];
136 // it with the lock held. Verify that they are always reading/writing 164 MultipleLockThread* thread_delegates[kNumThreads];
137 // consistent data.
138 const int kNumThreads = 5;
139 HANDLE threads[kNumThreads];
140 165
141 // Spawn the threads. 166 // Spawn the threads.
142 for (int index = 0; index < kNumThreads; ++index) { 167 for (int index = 0; index < kNumThreads; ++index) {
143 void *argument = reinterpret_cast<void*>(static_cast<INT_PTR>(index)); 168 PlatformThreadHandle pth;
144 threads[index] = reinterpret_cast<HANDLE>( 169 thread_delegates[index] = new MultipleLockThread(index);
145 _beginthreadex(NULL, 0, &MultipleLockThread, argument, 0, NULL)); 170 EXPECT_TRUE(PlatformThread::Create(0, thread_delegates[index], &pth));
146 EXPECT_NE(threads[index], static_cast<HANDLE>(NULL)); 171 thread_handles[index] = pth;
147 } 172 }
148 173
149 // Wait for the threads to finish. 174 // Wait for the threads to finish.
150 for (int index = 0; index < kNumThreads; ++index) { 175 for (int index = 0; index < kNumThreads; ++index) {
151 DWORD rv = WaitForSingleObject(threads[index], 60*1000); 176 PlatformThread::Join(thread_handles[index]);
152 EXPECT_EQ(rv, WAIT_OBJECT_0); // verify all threads finished 177 delete thread_delegates[index];
153 CloseHandle(threads[index]);
154 } 178 }
155 } 179 }
156 180 #endif
OLDNEW
« no previous file with comments | « base/base.xcodeproj/project.pbxproj ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698