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

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: good grief -- when will it end? 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 uint32_t TEST_MEMORY_SIZE = 1 << 20; // 1 MiB
15 const uint32_t TEST_MEMORY_PAGE = 64 << 10; // 64 KiB
16
17 } // namespace
18
19 namespace base {
20
Alexander Potapenko 2015/11/09 18:03:46 You're missing the tests for: -- using the alloca
bcwhite 2015/11/09 19:21:16 The ParallelismTest and CorruptionTest are intra-p
21 typedef SharedMemoryAllocator::Reference Reference;
22
23 class SharedMemoryAllocatorTest : public testing::Test {
24 public:
25 struct TestObject1 {
26 int32_t onething;
27 char oranother;
28 };
29
30 struct TestObject2 {
31 int thiis;
32 long that;
33 float andthe;
34 char other;
35 double thing;
36 };
37
38 SharedMemoryAllocatorTest() {
39 mem_segment_.reset(new char[TEST_MEMORY_SIZE]);
40 }
41
42 void SetUp() override {
43 allocator_.reset();
44 memset(mem_segment_.get(), 0, TEST_MEMORY_SIZE);
45 allocator_.reset(new SharedMemoryAllocator(
46 mem_segment_.get(), TEST_MEMORY_SIZE, TEST_MEMORY_PAGE));
47 }
48
49 void TearDown() override {
50 allocator_.reset();
51 }
52
53 int CountIterables() {
54 SharedMemoryAllocator::Iterator iter;
55 uint32_t type;
56 int count = 0;
57 for (allocator_->CreateIterator(&iter);
58 allocator_->GetNextIterable(&iter, &type) != 0;) {
59 count++;
60 }
61 return count;
62 }
63
64 scoped_ptr<char[]> mem_segment_;
65 scoped_ptr<SharedMemoryAllocator> allocator_;
66 };
67
68 TEST_F(SharedMemoryAllocatorTest, AllocateAndIterate) {
69 SharedMemoryAllocator::MemoryInfo meminfo0;
70 allocator_->GetMemoryInfo(&meminfo0);
71 EXPECT_EQ(TEST_MEMORY_SIZE, meminfo0.total);
72 EXPECT_GT(meminfo0.total, meminfo0.free);
73
74 Reference block1 = allocator_->Allocate(sizeof(TestObject1), 1);
75 EXPECT_NE(0, block1);
76 EXPECT_NE(nullptr, allocator_->GetAsObject<TestObject1>(block1, 1));
77 EXPECT_EQ(nullptr, allocator_->GetAsObject<TestObject2>(block1, 1));
78 EXPECT_LE(sizeof(TestObject1), allocator_->GetAllocSize(block1));
79 EXPECT_GE(sizeof(TestObject1) + 7, allocator_->GetAllocSize(block1));
80 SharedMemoryAllocator::MemoryInfo meminfo1;
81 allocator_->GetMemoryInfo(&meminfo1);
82 EXPECT_EQ(meminfo0.total, meminfo1.total);
83 EXPECT_GT(meminfo0.free, meminfo1.free);
84
85 SharedMemoryAllocator::Iterator iter;
86 uint32_t type;
87 allocator_->CreateIterator(&iter);
88 EXPECT_EQ(0, allocator_->GetNextIterable(&iter, &type));
89 allocator_->MakeIterable(block1);
90 EXPECT_EQ(block1, allocator_->GetNextIterable(&iter, &type));
91 EXPECT_EQ(1U, type);
92 EXPECT_EQ(0, allocator_->GetNextIterable(&iter, &type));
93
94 Reference block2 = allocator_->Allocate(sizeof(TestObject2), 2);
95 EXPECT_NE(0, block2);
96 EXPECT_NE(nullptr, allocator_->GetAsObject<TestObject2>(block2, 2));
97 EXPECT_EQ(nullptr, allocator_->GetAsObject<TestObject2>(block2, 1));
98 EXPECT_LE(sizeof(TestObject2), allocator_->GetAllocSize(block2));
99 EXPECT_GE(sizeof(TestObject2) + 7, allocator_->GetAllocSize(block2));
100 SharedMemoryAllocator::MemoryInfo meminfo2;
101 allocator_->GetMemoryInfo(&meminfo2);
102 EXPECT_EQ(meminfo1.total, meminfo2.total);
103 EXPECT_GT(meminfo1.free, meminfo2.free);
104
105 allocator_->MakeIterable(block2);
106 EXPECT_EQ(block2, allocator_->GetNextIterable(&iter, &type));
107 EXPECT_EQ(2U, type);
108 EXPECT_EQ(0, allocator_->GetNextIterable(&iter, &type));
109
110 EXPECT_FALSE(allocator_->IsFull());
111 EXPECT_FALSE(allocator_->IsCorrupt());
112 }
113
114 TEST_F(SharedMemoryAllocatorTest, PageTest) {
115 Reference block1 = allocator_->Allocate(TEST_MEMORY_PAGE / 2, 1);
116 EXPECT_LT(0, block1);
117 EXPECT_GT((int)TEST_MEMORY_PAGE, block1);
118
119 Reference block2 = allocator_->Allocate(TEST_MEMORY_PAGE - 16, 2);
120 EXPECT_EQ((int)TEST_MEMORY_PAGE, block2);
121
122 Reference block3 = allocator_->Allocate(99, 3);
123 EXPECT_EQ(2 * (int)TEST_MEMORY_PAGE, block3);
124 }
125
126 class AllocatorThread : public SimpleThread {
127 public:
128 AllocatorThread(const std::string& name,
129 void* base,
130 int32_t size,
131 int32_t page_size)
132 : SimpleThread(name, Options()),
133 count_(0),
134 iterable_(0),
135 allocator_(base, size, page_size) {}
136
137 void Run() override {
138 for (;;) {
139 int32_t size = (int32_t)base::RandInt(1, 99);
140 uint32_t type = (int32_t)base::RandInt(100, 999);
141 Reference block = allocator_.Allocate(size, type);
142 if (!block)
143 break;
144
145 count_++;
146 if (base::RandInt(0, 1)) {
147 allocator_.MakeIterable(block);
148 iterable_++;
149 }
150 }
151 }
152
153 int count_;
154 int iterable_;
155
156 private:
157 SharedMemoryAllocator allocator_;
158 };
159
160 TEST_F(SharedMemoryAllocatorTest, ParallelismTest) {
161 void* memory = mem_segment_.get();
162 AllocatorThread t1("t1", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
163 AllocatorThread t2("t2", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
164 AllocatorThread t3("t3", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
165 AllocatorThread t4("t4", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
166 AllocatorThread t5("t5", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
167
168 t1.Start();
169 t2.Start();
170 t3.Start();
171 t4.Start();
172 t5.Start();
173
174 int last_count = 0;
175 do {
176 int count = CountIterables();
177 EXPECT_LE(last_count, count);
178 } while (!allocator_->IsCorrupt() && !allocator_->IsFull());
179
180 t1.Join();
181 t2.Join();
182 t3.Join();
183 t4.Join();
184 t5.Join();
185
186 EXPECT_FALSE(allocator_->IsCorrupt());
187 EXPECT_EQ(CountIterables(),
188 t1.iterable_ + t2.iterable_ + t3.iterable_ + t4.iterable_ +
189 t5.iterable_);
190 }
191
192 // This test doesn't verify anything other than it doesn't crash.
193 TEST_F(SharedMemoryAllocatorTest, CorruptionTest) {
194 char* memory = mem_segment_.get();
195 AllocatorThread t1("t1", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
196 AllocatorThread t2("t2", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
197 AllocatorThread t3("t3", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
198 AllocatorThread t4("t4", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
199 AllocatorThread t5("t5", memory, TEST_MEMORY_SIZE, TEST_MEMORY_PAGE);
200
201 t1.Start();
202 t2.Start();
203 t3.Start();
204 t4.Start();
205 t5.Start();
206
207 do {
208 size_t offset = base::RandInt(0, TEST_MEMORY_SIZE - 1);
209 char value = base::RandInt(0, 255);
210 memory[offset] = value;
211 } while (!allocator_->IsCorrupt() && !allocator_->IsFull());
212
213 t1.Join();
214 t2.Join();
215 t3.Join();
216 t4.Join();
217 t5.Join();
218
219 CountIterables();
220 }
221
222 // Attempt to cause crashes or loops by expressly creating dangerous coditions.
223 TEST_F(SharedMemoryAllocatorTest, MaliciousTest) {
224 Reference block1 = allocator_->Allocate(sizeof(TestObject1), 1);
225 Reference block2 = allocator_->Allocate(sizeof(TestObject1), 2);
226 Reference block3 = allocator_->Allocate(sizeof(TestObject1), 3);
227 Reference block4 = allocator_->Allocate(sizeof(TestObject1), 3);
228 Reference block5 = allocator_->Allocate(sizeof(TestObject1), 3);
229 allocator_->MakeIterable(block1);
230 allocator_->MakeIterable(block2);
231 allocator_->MakeIterable(block3);
232 allocator_->MakeIterable(block4);
233 allocator_->MakeIterable(block5);
234 EXPECT_EQ(5, CountIterables());
235 EXPECT_FALSE(allocator_->IsCorrupt());
236
237 // Create loop in iterable list and ensure it doesn't hang.
238 int32_t* header4 = (int32_t*)(mem_segment_.get() + block4);
239 EXPECT_EQ(block5, header4[3]);
240 header4[3] = block3;
241 CountIterables(); // loop: 1-2-3-4-3
242 header4[3] = block2;
243 CountIterables(); // loop: 1-2-3-4-2
244 header4[3] = block1;
245 CountIterables(); // loop: 1-2-3-4-1
246 EXPECT_TRUE(allocator_->IsCorrupt());
247 }
248
249 } // 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