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

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

Issue 1410213004: Create "persistent memory allocator" for persisting and sharing objects. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: moved flags to Atomic32 Created 5 years, 1 month 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
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/memory/shared_memory_allocator.h"
6
7 #include "base/memory/scoped_ptr.h"
8 #include "base/rand_util.h"
9 #include "base/threading/simple_thread.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11
12 namespace {
13
14 const int32_t TEST_MEMORY_SIZE = 1 << 20; // 1 MiB
15 const int32_t TEST_MEMORY_PAGE = 64 << 10; // 64 KiB
16
17 } // namespace
18
19 namespace base {
20
21 class SharedMemoryAllocatorTest : public testing::Test {
22 public:
23 struct TestObject1 {
24 int32_t onething;
25 char oranother;
26 };
27
28 struct TestObject2 {
29 int thiis;
30 long that;
31 float andthe;
32 char other;
33 double thing;
34 };
35
36 SharedMemoryAllocatorTest() {
37 mem_segment_.reset(new char[TEST_MEMORY_SIZE]);
38 }
39
40 void SetUp() override {
41 allocator_.reset();
42 memset(mem_segment_.get(), 0, TEST_MEMORY_SIZE);
43 allocator_.reset(new SharedMemoryAllocator(mem_segment_.get(),
44 TEST_MEMORY_SIZE,
45 TEST_MEMORY_PAGE));
46 }
47
48 void TearDown() override {
49 allocator_.reset();
50 }
51
52 int CountIterables() {
53 SharedMemoryAllocator::Iterator iter;
54 int32_t type;
55 int count = 0;
56 for (allocator_->CreateIterator(&iter);
57 allocator_->GetNextIterable(&iter, &type) != 0;) {
58 count++;
59 }
60 return count;
61 }
62
63 scoped_ptr<char[]> mem_segment_;
64 scoped_ptr<SharedMemoryAllocator> allocator_;
65 };
66
67 TEST_F(SharedMemoryAllocatorTest, AllocateAndIterate) {
68 SharedMemoryAllocator::MemoryInfo meminfo0;
69 allocator_->GetMemoryInfo(&meminfo0);
70 EXPECT_EQ(TEST_MEMORY_SIZE, meminfo0.total);
71 EXPECT_GT(meminfo0.total, meminfo0.free);
72
73 int32_t block1 = allocator_->Allocate(sizeof(TestObject1), 1);
74 EXPECT_NE(0, block1);
75 EXPECT_NE(nullptr, allocator_->GetType<TestObject1>(block1, 1));
76 EXPECT_EQ(nullptr, allocator_->GetType<TestObject2>(block1, 1));
77 SharedMemoryAllocator::MemoryInfo meminfo1;
78 allocator_->GetMemoryInfo(&meminfo1);
79 EXPECT_EQ(meminfo0.total, meminfo1.total);
80 EXPECT_GT(meminfo0.free, meminfo1.free);
81
82 SharedMemoryAllocator::Iterator iter;
83 int32_t type;
84 allocator_->CreateIterator(&iter);
85 EXPECT_EQ(0, allocator_->GetNextIterable(&iter, &type));
86 allocator_->MakeIterable(block1);
87 EXPECT_EQ(block1, allocator_->GetNextIterable(&iter, &type));
88 EXPECT_EQ(1, type);
89 EXPECT_EQ(0, allocator_->GetNextIterable(&iter, &type));
90
91 int32_t block2 = allocator_->Allocate(sizeof(TestObject2), 2);
92 EXPECT_NE(0, block2);
93 EXPECT_NE(nullptr, allocator_->GetType<TestObject2>(block2, 2));
94 EXPECT_EQ(nullptr, allocator_->GetType<TestObject2>(block2, 1));
95 SharedMemoryAllocator::MemoryInfo meminfo2;
96 allocator_->GetMemoryInfo(&meminfo2);
97 EXPECT_EQ(meminfo1.total, meminfo2.total);
98 EXPECT_GT(meminfo1.free, meminfo2.free);
99
100 allocator_->MakeIterable(block2);
101 EXPECT_EQ(block2, allocator_->GetNextIterable(&iter, &type));
102 EXPECT_EQ(2, type);
103 EXPECT_EQ(0, allocator_->GetNextIterable(&iter, &type));
104
105 EXPECT_FALSE(allocator_->IsFull());
106 EXPECT_FALSE(allocator_->IsCorrupted());
107 }
108
109 TEST_F(SharedMemoryAllocatorTest, PageTest) {
110 int32_t block1 = allocator_->Allocate(TEST_MEMORY_PAGE / 2, 1);
111 EXPECT_LT(0, block1);
112 EXPECT_GT(TEST_MEMORY_PAGE, block1);
113
114 int32_t block2 = allocator_->Allocate(TEST_MEMORY_PAGE - 16, 2);
115 EXPECT_EQ(TEST_MEMORY_PAGE, block2);
116
117 int32_t block3 = allocator_->Allocate(99, 3);
118 EXPECT_EQ(2 * TEST_MEMORY_PAGE, block3);
119 }
120
121 class AllocatorThread : public SimpleThread {
122 public:
123 AllocatorThread(const std::string& name, void* base, int32_t size,
124 int32_t page_size)
125 : SimpleThread(name, Options()),
126 count_(0),
127 iterable_(0),
128 allocator_(base, size, page_size) {
129 }
130
131 void Run() override {
132 for (;;) {
133 int32_t size = (int32_t)base::RandInt(1, 99);
134 int32_t type = (int32_t)base::RandInt(100, 999);
135 int32_t block = allocator_.Allocate(size, type);
136 if (!block)
137 break;
138
139 count_++;
140 if (base::RandInt(0, 1)) {
141 allocator_.MakeIterable(block);
142 iterable_++;
143 }
144 }
145 }
146
147 int count_;
148 int iterable_;
149
150 private:
151 SharedMemoryAllocator allocator_;
152 };
153
154 TEST_F(SharedMemoryAllocatorTest, ParallelismTest) {
155 void* memory = mem_segment_.get();
156 AllocatorThread t1("t1", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
157 AllocatorThread t2("t2", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
158 AllocatorThread t3("t3", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
159 AllocatorThread t4("t4", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
160 AllocatorThread t5("t5", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
Dmitry Vyukov 2015/11/03 14:06:46 Also run iteration thread concurrently.
bcwhite 2015/11/03 16:28:20 The test thread is doing that concurrently with th
161
162 t1.Start();
163 t2.Start();
164 t3.Start();
165 t4.Start();
166 t5.Start();
167
168 int last_count = 0;
169 do {
170 int count = CountIterables();
171 EXPECT_LE(last_count, count);
172 } while (!allocator_->IsCorrupted() && !allocator_->IsFull());
173
174 t1.Join();
175 t2.Join();
176 t3.Join();
177 t4.Join();
178 t5.Join();
179
180 EXPECT_FALSE(allocator_->IsCorrupted());
181 EXPECT_EQ(CountIterables(),
182 t1.iterable_ + t2.iterable_ + t3.iterable_ + t4.iterable_ +
183 t5.iterable_);
184 }
185
186 // This test doesn't verify anything other than it doesn't crash.
187 TEST_F(SharedMemoryAllocatorTest, CorruptionTest) {
188 char* memory = mem_segment_.get();
189 AllocatorThread t1("t1", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
190 AllocatorThread t2("t2", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
191 AllocatorThread t3("t3", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
192 AllocatorThread t4("t4", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
193 AllocatorThread t5("t5", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
Dmitry Vyukov 2015/11/03 14:06:46 Also run iteration thread concurrently.
194
195 t1.Start();
196 t2.Start();
197 t3.Start();
198 t4.Start();
199 t5.Start();
200
201 do {
202 size_t offset = base::RandInt(0, TEST_MEMORY_SIZE - 1);
203 char value = base::RandInt(0, 255);
204 memory[offset] = value;
205 } while (!allocator_->IsCorrupted() && !allocator_->IsFull());
206
207 t1.Join();
208 t2.Join();
209 t3.Join();
210 t4.Join();
211 t5.Join();
212
213 CountIterables();
214 }
215
216 // Attempt to cause crashes or loops by expressly creating dangerous coditions.
217 TEST_F(SharedMemoryAllocatorTest, MaliciousTest) {
218 int32_t block1 = allocator_->Allocate(sizeof(TestObject1), 1);
219 int32_t block2 = allocator_->Allocate(sizeof(TestObject1), 2);
220 int32_t block3 = allocator_->Allocate(sizeof(TestObject1), 3);
221 int32_t block4 = allocator_->Allocate(sizeof(TestObject1), 3);
222 int32_t block5 = allocator_->Allocate(sizeof(TestObject1), 3);
223 allocator_->MakeIterable(block1);
224 allocator_->MakeIterable(block2);
225 allocator_->MakeIterable(block3);
226 allocator_->MakeIterable(block4);
227 allocator_->MakeIterable(block5);
228 EXPECT_EQ(5, CountIterables());
229 EXPECT_FALSE(allocator_->IsCorrupted());
230
231 // Create loop in iterable list and ensure it doesn't hang.
232 int32_t* header4 = (int32_t*)(mem_segment_.get() + block4);
233 EXPECT_EQ(block5, header4[3]);
234 header4[3] = block3;
235 CountIterables(); // loop: 1-2-3-4-3
236 header4[3] = block2;
237 CountIterables(); // loop: 1-2-3-4-2
238 header4[3] = block1;
239 CountIterables(); // loop: 1-2-3-4-1
240 EXPECT_TRUE(allocator_->IsCorrupted());
241 }
242
243 } // namespace base
OLDNEW
« base/memory/shared_memory_allocator.cc ('K') | « base/memory/shared_memory_allocator.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698