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

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: rebased 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(
44 mem_segment_.get(), TEST_MEMORY_SIZE, TEST_MEMORY_PAGE));
45 }
46
47 void TearDown() override {
48 allocator_.reset();
49 }
50
51 int CountIterables() {
52 SharedMemoryAllocator::Iterator iter;
53 int32_t type;
54 int count = 0;
55 for (allocator_->CreateIterator(&iter);
56 allocator_->GetNextIterable(&iter, &type) != 0;) {
57 count++;
58 }
59 return count;
60 }
61
62 scoped_ptr<char[]> mem_segment_;
63 scoped_ptr<SharedMemoryAllocator> allocator_;
64 };
65
66 TEST_F(SharedMemoryAllocatorTest, AllocateAndIterate) {
67 SharedMemoryAllocator::MemoryInfo meminfo0;
68 allocator_->GetMemoryInfo(&meminfo0);
69 EXPECT_EQ(TEST_MEMORY_SIZE, meminfo0.total);
70 EXPECT_GT(meminfo0.total, meminfo0.free);
71
72 int32_t block1 = allocator_->Allocate(sizeof(TestObject1), 1);
73 EXPECT_NE(0, block1);
74 EXPECT_NE(nullptr, allocator_->GetAsObject<TestObject1>(block1, 1));
75 EXPECT_EQ(nullptr, allocator_->GetAsObject<TestObject2>(block1, 1));
76 SharedMemoryAllocator::MemoryInfo meminfo1;
77 allocator_->GetMemoryInfo(&meminfo1);
78 EXPECT_EQ(meminfo0.total, meminfo1.total);
79 EXPECT_GT(meminfo0.free, meminfo1.free);
80
81 SharedMemoryAllocator::Iterator iter;
82 int32_t type;
83 allocator_->CreateIterator(&iter);
84 EXPECT_EQ(0, allocator_->GetNextIterable(&iter, &type));
85 allocator_->MakeIterable(block1);
86 EXPECT_EQ(block1, allocator_->GetNextIterable(&iter, &type));
87 EXPECT_EQ(1, type);
88 EXPECT_EQ(0, allocator_->GetNextIterable(&iter, &type));
89
90 int32_t block2 = allocator_->Allocate(sizeof(TestObject2), 2);
91 EXPECT_NE(0, block2);
92 EXPECT_NE(nullptr, allocator_->GetAsObject<TestObject2>(block2, 2));
93 EXPECT_EQ(nullptr, allocator_->GetAsObject<TestObject2>(block2, 1));
94 SharedMemoryAllocator::MemoryInfo meminfo2;
95 allocator_->GetMemoryInfo(&meminfo2);
96 EXPECT_EQ(meminfo1.total, meminfo2.total);
97 EXPECT_GT(meminfo1.free, meminfo2.free);
98
99 allocator_->MakeIterable(block2);
100 EXPECT_EQ(block2, allocator_->GetNextIterable(&iter, &type));
101 EXPECT_EQ(2, type);
102 EXPECT_EQ(0, allocator_->GetNextIterable(&iter, &type));
103
104 EXPECT_FALSE(allocator_->IsFull());
105 EXPECT_FALSE(allocator_->IsCorrupted());
106 }
107
108 TEST_F(SharedMemoryAllocatorTest, PageTest) {
109 int32_t block1 = allocator_->Allocate(TEST_MEMORY_PAGE / 2, 1);
110 EXPECT_LT(0, block1);
111 EXPECT_GT(TEST_MEMORY_PAGE, block1);
112
113 int32_t block2 = allocator_->Allocate(TEST_MEMORY_PAGE - 16, 2);
114 EXPECT_EQ(TEST_MEMORY_PAGE, block2);
115
116 int32_t block3 = allocator_->Allocate(99, 3);
117 EXPECT_EQ(2 * TEST_MEMORY_PAGE, block3);
118 }
119
120 class AllocatorThread : public SimpleThread {
121 public:
122 AllocatorThread(const std::string& name,
123 void* base,
124 int32_t size,
125 int32_t page_size)
126 : SimpleThread(name, Options()),
127 count_(0),
128 iterable_(0),
129 allocator_(base, size, page_size) {}
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);
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);
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