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

Side by Side Diff: content/common/host_discardable_shared_memory_manager_unittest.cc

Issue 2459733002: Move discardable memory to //components from //content (Closed)
Patch Set: Fix build error Created 4 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
« no previous file with comments | « content/common/host_discardable_shared_memory_manager.cc ('k') | content/ppapi_plugin/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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 "content/common/host_discardable_shared_memory_manager.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <string.h>
10
11 #include "base/threading/simple_thread.h"
12 #include "content/public/common/child_process_host.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace content {
16 namespace {
17
18 class TestDiscardableSharedMemory : public base::DiscardableSharedMemory {
19 public:
20 TestDiscardableSharedMemory() {}
21
22 explicit TestDiscardableSharedMemory(base::SharedMemoryHandle handle)
23 : DiscardableSharedMemory(handle) {}
24
25 void SetNow(base::Time now) { now_ = now; }
26
27 private:
28 // Overriden from base::DiscardableSharedMemory:
29 base::Time Now() const override { return now_; }
30
31 base::Time now_;
32 };
33
34 class TestHostDiscardableSharedMemoryManager
35 : public HostDiscardableSharedMemoryManager {
36 public:
37 TestHostDiscardableSharedMemoryManager()
38 : enforce_memory_policy_pending_(false) {}
39
40 void SetNow(base::Time now) { now_ = now; }
41
42 void set_enforce_memory_policy_pending(bool enforce_memory_policy_pending) {
43 enforce_memory_policy_pending_ = enforce_memory_policy_pending;
44 }
45 bool enforce_memory_policy_pending() const {
46 return enforce_memory_policy_pending_;
47 }
48
49 private:
50 // Overriden from HostDiscardableSharedMemoryManager:
51 base::Time Now() const override { return now_; }
52 void ScheduleEnforceMemoryPolicy() override {
53 enforce_memory_policy_pending_ = true;
54 }
55
56 base::Time now_;
57 bool enforce_memory_policy_pending_;
58 };
59
60 class HostDiscardableSharedMemoryManagerTest : public testing::Test {
61 protected:
62 // Overridden from testing::Test:
63 void SetUp() override {
64 manager_.reset(new TestHostDiscardableSharedMemoryManager);
65 }
66
67 // HostDiscardableSharedMemoryManager requires a message loop.
68 base::MessageLoop message_loop_;
69 std::unique_ptr<TestHostDiscardableSharedMemoryManager> manager_;
70 };
71
72 TEST_F(HostDiscardableSharedMemoryManagerTest, AllocateForChild) {
73 const int kDataSize = 1024;
74 uint8_t data[kDataSize];
75 memset(data, 0x80, kDataSize);
76
77 base::SharedMemoryHandle shared_handle;
78 manager_->AllocateLockedDiscardableSharedMemoryForChild(
79 base::GetCurrentProcessHandle(), ChildProcessHost::kInvalidUniqueID,
80 kDataSize, 0, &shared_handle);
81 ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle));
82
83 TestDiscardableSharedMemory memory(shared_handle);
84 bool rv = memory.Map(kDataSize);
85 ASSERT_TRUE(rv);
86
87 memcpy(memory.memory(), data, kDataSize);
88 memory.SetNow(base::Time::FromDoubleT(1));
89 memory.Unlock(0, 0);
90
91 ASSERT_EQ(base::DiscardableSharedMemory::SUCCESS, memory.Lock(0, 0));
92 EXPECT_EQ(memcmp(data, memory.memory(), kDataSize), 0);
93 memory.Unlock(0, 0);
94 }
95
96 TEST_F(HostDiscardableSharedMemoryManagerTest, Purge) {
97 const int kDataSize = 1024;
98
99 base::SharedMemoryHandle shared_handle1;
100 manager_->AllocateLockedDiscardableSharedMemoryForChild(
101 base::GetCurrentProcessHandle(), ChildProcessHost::kInvalidUniqueID,
102 kDataSize, 1, &shared_handle1);
103 ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle1));
104
105 TestDiscardableSharedMemory memory1(shared_handle1);
106 bool rv = memory1.Map(kDataSize);
107 ASSERT_TRUE(rv);
108
109 base::SharedMemoryHandle shared_handle2;
110 manager_->AllocateLockedDiscardableSharedMemoryForChild(
111 base::GetCurrentProcessHandle(), ChildProcessHost::kInvalidUniqueID,
112 kDataSize, 2, &shared_handle2);
113 ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle2));
114
115 TestDiscardableSharedMemory memory2(shared_handle2);
116 rv = memory2.Map(kDataSize);
117 ASSERT_TRUE(rv);
118
119 // Enough memory for both allocations.
120 manager_->SetNow(base::Time::FromDoubleT(1));
121 manager_->SetMemoryLimit(memory1.mapped_size() + memory2.mapped_size());
122
123 memory1.SetNow(base::Time::FromDoubleT(2));
124 memory1.Unlock(0, 0);
125 memory2.SetNow(base::Time::FromDoubleT(2));
126 memory2.Unlock(0, 0);
127
128 // Manager should not have to schedule another call to EnforceMemoryPolicy().
129 manager_->SetNow(base::Time::FromDoubleT(3));
130 manager_->EnforceMemoryPolicy();
131 EXPECT_FALSE(manager_->enforce_memory_policy_pending());
132
133 // Memory should still be resident.
134 EXPECT_TRUE(memory1.IsMemoryResident());
135 EXPECT_TRUE(memory2.IsMemoryResident());
136
137 auto lock_rv = memory1.Lock(0, 0);
138 EXPECT_EQ(base::DiscardableSharedMemory::SUCCESS, lock_rv);
139 lock_rv = memory2.Lock(0, 0);
140 EXPECT_EQ(base::DiscardableSharedMemory::SUCCESS, lock_rv);
141
142 memory1.SetNow(base::Time::FromDoubleT(4));
143 memory1.Unlock(0, 0);
144 memory2.SetNow(base::Time::FromDoubleT(5));
145 memory2.Unlock(0, 0);
146
147 // Just enough memory for one allocation.
148 manager_->SetNow(base::Time::FromDoubleT(6));
149 manager_->SetMemoryLimit(memory2.mapped_size());
150 EXPECT_FALSE(manager_->enforce_memory_policy_pending());
151
152 // LRU allocation should still be resident.
153 EXPECT_FALSE(memory1.IsMemoryResident());
154 EXPECT_TRUE(memory2.IsMemoryResident());
155
156 lock_rv = memory1.Lock(0, 0);
157 EXPECT_EQ(base::DiscardableSharedMemory::FAILED, lock_rv);
158 lock_rv = memory2.Lock(0, 0);
159 EXPECT_EQ(base::DiscardableSharedMemory::SUCCESS, lock_rv);
160 }
161
162 TEST_F(HostDiscardableSharedMemoryManagerTest, EnforceMemoryPolicy) {
163 const int kDataSize = 1024;
164
165 base::SharedMemoryHandle shared_handle;
166 manager_->AllocateLockedDiscardableSharedMemoryForChild(
167 base::GetCurrentProcessHandle(), ChildProcessHost::kInvalidUniqueID,
168 kDataSize, 0, &shared_handle);
169 ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle));
170
171 TestDiscardableSharedMemory memory(shared_handle);
172 bool rv = memory.Map(kDataSize);
173 ASSERT_TRUE(rv);
174
175 // Not enough memory for one allocation.
176 manager_->SetNow(base::Time::FromDoubleT(1));
177 manager_->SetMemoryLimit(memory.mapped_size() - 1);
178 // We need to enforce memory policy as our memory usage is currently above
179 // the limit.
180 EXPECT_TRUE(manager_->enforce_memory_policy_pending());
181
182 manager_->set_enforce_memory_policy_pending(false);
183 manager_->SetNow(base::Time::FromDoubleT(2));
184 manager_->EnforceMemoryPolicy();
185 // Still need to enforce memory policy as nothing can be purged.
186 EXPECT_TRUE(manager_->enforce_memory_policy_pending());
187
188 memory.SetNow(base::Time::FromDoubleT(3));
189 memory.Unlock(0, 0);
190
191 manager_->set_enforce_memory_policy_pending(false);
192 manager_->SetNow(base::Time::FromDoubleT(4));
193 manager_->EnforceMemoryPolicy();
194 // Memory policy should have successfully been enforced.
195 EXPECT_FALSE(manager_->enforce_memory_policy_pending());
196
197 EXPECT_EQ(base::DiscardableSharedMemory::FAILED, memory.Lock(0, 0));
198 }
199
200 TEST_F(HostDiscardableSharedMemoryManagerTest,
201 ReduceMemoryAfterSegmentHasBeenDeleted) {
202 const int kDataSize = 1024;
203
204 base::SharedMemoryHandle shared_handle1;
205 manager_->AllocateLockedDiscardableSharedMemoryForChild(
206 base::GetCurrentProcessHandle(), ChildProcessHost::kInvalidUniqueID,
207 kDataSize, 1, &shared_handle1);
208 ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle1));
209
210 TestDiscardableSharedMemory memory1(shared_handle1);
211 bool rv = memory1.Map(kDataSize);
212 ASSERT_TRUE(rv);
213
214 base::SharedMemoryHandle shared_handle2;
215 manager_->AllocateLockedDiscardableSharedMemoryForChild(
216 base::GetCurrentProcessHandle(), ChildProcessHost::kInvalidUniqueID,
217 kDataSize, 2, &shared_handle2);
218 ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle2));
219
220 TestDiscardableSharedMemory memory2(shared_handle2);
221 rv = memory2.Map(kDataSize);
222 ASSERT_TRUE(rv);
223
224 // Unlock and delete segment 1.
225 memory1.SetNow(base::Time::FromDoubleT(1));
226 memory1.Unlock(0, 0);
227 memory1.Unmap();
228 memory1.Close();
229 manager_->ChildDeletedDiscardableSharedMemory(
230 1, ChildProcessHost::kInvalidUniqueID);
231
232 // Make sure the manager is able to reduce memory after the segment 1 was
233 // deleted.
234 manager_->SetNow(base::Time::FromDoubleT(2));
235 manager_->SetMemoryLimit(0);
236
237 // Unlock segment 2.
238 memory2.SetNow(base::Time::FromDoubleT(3));
239 memory2.Unlock(0, 0);
240 }
241
242 class HostDiscardableSharedMemoryManagerScheduleEnforceMemoryPolicyTest
243 : public testing::Test {
244 protected:
245 // Overridden from testing::Test:
246 void SetUp() override {
247 manager_.reset(new HostDiscardableSharedMemoryManager);
248 }
249
250 // HostDiscardableSharedMemoryManager requires a message loop.
251 base::MessageLoop message_loop_;
252 std::unique_ptr<HostDiscardableSharedMemoryManager> manager_;
253 };
254
255 class SetMemoryLimitRunner : public base::DelegateSimpleThread::Delegate {
256 public:
257 SetMemoryLimitRunner(HostDiscardableSharedMemoryManager* manager,
258 size_t limit)
259 : manager_(manager), limit_(limit) {}
260 ~SetMemoryLimitRunner() override {}
261
262 void Run() override { manager_->SetMemoryLimit(limit_); }
263
264 private:
265 HostDiscardableSharedMemoryManager* const manager_;
266 const size_t limit_;
267 };
268
269 TEST_F(HostDiscardableSharedMemoryManagerScheduleEnforceMemoryPolicyTest,
270 SetMemoryLimitOnSimpleThread) {
271 const int kDataSize = 1024;
272
273 base::SharedMemoryHandle shared_handle;
274 manager_->AllocateLockedDiscardableSharedMemoryForChild(
275 base::GetCurrentProcessHandle(), ChildProcessHost::kInvalidUniqueID,
276 kDataSize, 0, &shared_handle);
277 ASSERT_TRUE(base::SharedMemory::IsHandleValid(shared_handle));
278
279 // Set the memory limit to a value that will require EnforceMemoryPolicy()
280 // to be schedule on a thread without a message loop.
281 SetMemoryLimitRunner runner(manager_.get(), kDataSize - 1);
282 base::DelegateSimpleThread thread(&runner, "memory_limit_setter");
283 thread.Start();
284 thread.Join();
285 }
286
287 } // namespace
288 } // namespace content
OLDNEW
« no previous file with comments | « content/common/host_discardable_shared_memory_manager.cc ('k') | content/ppapi_plugin/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698