OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 "content/common/discardable_shared_memory_heap.h" | 5 #include "content/common/discardable_shared_memory_heap.h" |
6 | 6 |
7 #include "base/memory/discardable_shared_memory.h" | 7 #include "base/memory/discardable_shared_memory.h" |
8 #include "base/process/process_metrics.h" | 8 #include "base/process/process_metrics.h" |
9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
10 | 10 |
11 namespace content { | 11 namespace content { |
12 namespace { | 12 namespace { |
13 | 13 |
14 class DiscardableSharedMemoryHeapTest : public testing::Test {}; | 14 TEST(DiscardableSharedMemoryHeapTest, Basic) { |
15 | |
16 TEST_F(DiscardableSharedMemoryHeapTest, Basic) { | |
17 size_t block_size = base::GetPageSize(); | 15 size_t block_size = base::GetPageSize(); |
18 DiscardableSharedMemoryHeap heap(block_size); | 16 DiscardableSharedMemoryHeap heap(block_size); |
19 | 17 |
| 18 // Initial size should be 0. |
| 19 EXPECT_EQ(0u, heap.GetSize()); |
| 20 |
| 21 // Initial free list size should be 0. |
| 22 EXPECT_EQ(0u, heap.GetFreeListSize()); |
| 23 |
20 // Free list is initially empty. | 24 // Free list is initially empty. |
21 EXPECT_FALSE(heap.SearchFreeList(1)); | 25 EXPECT_FALSE(heap.SearchFreeList(1)); |
22 | 26 |
23 const size_t kBlocks = 10; | 27 const size_t kBlocks = 10; |
24 size_t memory_size = block_size * kBlocks; | 28 size_t memory_size = block_size * kBlocks; |
25 | 29 |
26 scoped_ptr<base::DiscardableSharedMemory> memory( | 30 scoped_ptr<base::DiscardableSharedMemory> memory( |
27 new base::DiscardableSharedMemory); | 31 new base::DiscardableSharedMemory); |
28 ASSERT_TRUE(memory->CreateAndMap(memory_size)); | 32 ASSERT_TRUE(memory->CreateAndMap(memory_size)); |
29 | 33 |
30 // Create new span for memory. | 34 // Create new span for memory. |
31 scoped_ptr<DiscardableSharedMemoryHeap::Span> new_span( | 35 scoped_ptr<DiscardableSharedMemoryHeap::Span> new_span( |
32 heap.Grow(memory.Pass(), memory_size)); | 36 heap.Grow(memory.Pass(), memory_size)); |
33 | 37 |
| 38 // Size should match |memory_size|. |
| 39 EXPECT_EQ(memory_size, heap.GetSize()); |
| 40 |
| 41 // Free list size should still be 0. |
| 42 EXPECT_EQ(0u, heap.GetFreeListSize()); |
| 43 |
34 // Free list should still be empty as |new_span| is currently in use. | 44 // Free list should still be empty as |new_span| is currently in use. |
35 EXPECT_FALSE(heap.SearchFreeList(1)); | 45 EXPECT_FALSE(heap.SearchFreeList(1)); |
36 | 46 |
37 // Done using |new_span|. Merge it into the free list. | 47 // Done using |new_span|. Merge it into the free list. |
38 heap.MergeIntoFreeList(new_span.Pass()); | 48 heap.MergeIntoFreeList(new_span.Pass()); |
39 | 49 |
| 50 // Free list size should now match |memory_size|. |
| 51 EXPECT_EQ(memory_size, heap.GetFreeListSize()); |
| 52 |
40 // Free list should not contain a span that is larger than kBlocks. | 53 // Free list should not contain a span that is larger than kBlocks. |
41 EXPECT_FALSE(heap.SearchFreeList(kBlocks + 1)); | 54 EXPECT_FALSE(heap.SearchFreeList(kBlocks + 1)); |
42 | 55 |
43 // Free list should contain a span that satisfies the request for kBlocks. | 56 // Free list should contain a span that satisfies the request for kBlocks. |
44 scoped_ptr<DiscardableSharedMemoryHeap::Span> span = | 57 scoped_ptr<DiscardableSharedMemoryHeap::Span> span = |
45 heap.SearchFreeList(kBlocks); | 58 heap.SearchFreeList(kBlocks); |
46 ASSERT_TRUE(span); | 59 ASSERT_TRUE(span); |
47 | 60 |
48 // Free list should be empty again. | 61 // Free list should be empty again. |
49 EXPECT_FALSE(heap.SearchFreeList(1)); | 62 EXPECT_FALSE(heap.SearchFreeList(1)); |
50 | 63 |
51 // Merge it into the free list again. | 64 // Merge it into the free list again. |
52 heap.MergeIntoFreeList(span.Pass()); | 65 heap.MergeIntoFreeList(span.Pass()); |
53 } | 66 } |
54 | 67 |
55 TEST_F(DiscardableSharedMemoryHeapTest, SplitAndMerge) { | 68 TEST(DiscardableSharedMemoryHeapTest, SplitAndMerge) { |
56 size_t block_size = base::GetPageSize(); | 69 size_t block_size = base::GetPageSize(); |
57 DiscardableSharedMemoryHeap heap(block_size); | 70 DiscardableSharedMemoryHeap heap(block_size); |
58 | 71 |
59 const size_t kBlocks = 6; | 72 const size_t kBlocks = 6; |
60 size_t memory_size = block_size * kBlocks; | 73 size_t memory_size = block_size * kBlocks; |
61 | 74 |
62 scoped_ptr<base::DiscardableSharedMemory> memory( | 75 scoped_ptr<base::DiscardableSharedMemory> memory( |
63 new base::DiscardableSharedMemory); | 76 new base::DiscardableSharedMemory); |
64 ASSERT_TRUE(memory->CreateAndMap(memory_size)); | 77 ASSERT_TRUE(memory->CreateAndMap(memory_size)); |
65 scoped_ptr<DiscardableSharedMemoryHeap::Span> new_span( | 78 scoped_ptr<DiscardableSharedMemoryHeap::Span> new_span( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 | 111 |
99 // All memory has been returned to the free list. | 112 // All memory has been returned to the free list. |
100 scoped_ptr<DiscardableSharedMemoryHeap::Span> large_span = | 113 scoped_ptr<DiscardableSharedMemoryHeap::Span> large_span = |
101 heap.SearchFreeList(kBlocks); | 114 heap.SearchFreeList(kBlocks); |
102 ASSERT_TRUE(large_span); | 115 ASSERT_TRUE(large_span); |
103 | 116 |
104 // Merge it into the free list again. | 117 // Merge it into the free list again. |
105 heap.MergeIntoFreeList(large_span.Pass()); | 118 heap.MergeIntoFreeList(large_span.Pass()); |
106 } | 119 } |
107 | 120 |
108 TEST_F(DiscardableSharedMemoryHeapTest, MergeSingleBlockSpan) { | 121 TEST(DiscardableSharedMemoryHeapTest, MergeSingleBlockSpan) { |
109 size_t block_size = base::GetPageSize(); | 122 size_t block_size = base::GetPageSize(); |
110 DiscardableSharedMemoryHeap heap(block_size); | 123 DiscardableSharedMemoryHeap heap(block_size); |
111 | 124 |
112 const size_t kBlocks = 6; | 125 const size_t kBlocks = 6; |
113 size_t memory_size = block_size * kBlocks; | 126 size_t memory_size = block_size * kBlocks; |
114 | 127 |
115 scoped_ptr<base::DiscardableSharedMemory> memory( | 128 scoped_ptr<base::DiscardableSharedMemory> memory( |
116 new base::DiscardableSharedMemory); | 129 new base::DiscardableSharedMemory); |
117 ASSERT_TRUE(memory->CreateAndMap(memory_size)); | 130 ASSERT_TRUE(memory->CreateAndMap(memory_size)); |
118 scoped_ptr<DiscardableSharedMemoryHeap::Span> new_span( | 131 scoped_ptr<DiscardableSharedMemoryHeap::Span> new_span( |
119 heap.Grow(memory.Pass(), memory_size)); | 132 heap.Grow(memory.Pass(), memory_size)); |
120 | 133 |
121 // Split span into two. | 134 // Split span into two. |
122 scoped_ptr<DiscardableSharedMemoryHeap::Span> leftover = | 135 scoped_ptr<DiscardableSharedMemoryHeap::Span> leftover = |
123 heap.Split(new_span.get(), 5); | 136 heap.Split(new_span.get(), 5); |
124 ASSERT_TRUE(leftover); | 137 ASSERT_TRUE(leftover); |
125 | 138 |
126 // Merge |new_span| into free list. | 139 // Merge |new_span| into free list. |
127 heap.MergeIntoFreeList(new_span.Pass()); | 140 heap.MergeIntoFreeList(new_span.Pass()); |
128 | 141 |
129 // Merge |leftover| into free list. | 142 // Merge |leftover| into free list. |
130 heap.MergeIntoFreeList(leftover.Pass()); | 143 heap.MergeIntoFreeList(leftover.Pass()); |
131 } | 144 } |
132 | 145 |
133 TEST_F(DiscardableSharedMemoryHeapTest, Grow) { | 146 TEST(DiscardableSharedMemoryHeapTest, Grow) { |
134 size_t block_size = base::GetPageSize(); | 147 size_t block_size = base::GetPageSize(); |
135 DiscardableSharedMemoryHeap heap(block_size); | 148 DiscardableSharedMemoryHeap heap(block_size); |
136 | 149 |
137 scoped_ptr<base::DiscardableSharedMemory> memory1( | 150 scoped_ptr<base::DiscardableSharedMemory> memory1( |
138 new base::DiscardableSharedMemory); | 151 new base::DiscardableSharedMemory); |
139 ASSERT_TRUE(memory1->CreateAndMap(block_size)); | 152 ASSERT_TRUE(memory1->CreateAndMap(block_size)); |
140 heap.MergeIntoFreeList(heap.Grow(memory1.Pass(), block_size).Pass()); | 153 heap.MergeIntoFreeList(heap.Grow(memory1.Pass(), block_size).Pass()); |
141 | 154 |
142 // Remove a span from free list. | 155 // Remove a span from free list. |
143 scoped_ptr<DiscardableSharedMemoryHeap::Span> span1 = heap.SearchFreeList(1); | 156 scoped_ptr<DiscardableSharedMemoryHeap::Span> span1 = heap.SearchFreeList(1); |
(...skipping 10 matching lines...) Expand all Loading... |
154 | 167 |
155 // Memory should now be available. | 168 // Memory should now be available. |
156 scoped_ptr<DiscardableSharedMemoryHeap::Span> span2 = heap.SearchFreeList(1); | 169 scoped_ptr<DiscardableSharedMemoryHeap::Span> span2 = heap.SearchFreeList(1); |
157 EXPECT_TRUE(span2); | 170 EXPECT_TRUE(span2); |
158 | 171 |
159 // Merge spans into the free list again. | 172 // Merge spans into the free list again. |
160 heap.MergeIntoFreeList(span1.Pass()); | 173 heap.MergeIntoFreeList(span1.Pass()); |
161 heap.MergeIntoFreeList(span2.Pass()); | 174 heap.MergeIntoFreeList(span2.Pass()); |
162 } | 175 } |
163 | 176 |
164 TEST_F(DiscardableSharedMemoryHeapTest, ReleaseFreeMemory) { | 177 TEST(DiscardableSharedMemoryHeapTest, ReleaseFreeMemory) { |
165 size_t block_size = base::GetPageSize(); | 178 size_t block_size = base::GetPageSize(); |
166 DiscardableSharedMemoryHeap heap(block_size); | 179 DiscardableSharedMemoryHeap heap(block_size); |
167 | 180 |
| 181 scoped_ptr<base::DiscardableSharedMemory> memory( |
| 182 new base::DiscardableSharedMemory); |
| 183 ASSERT_TRUE(memory->CreateAndMap(block_size)); |
| 184 scoped_ptr<DiscardableSharedMemoryHeap::Span> span = |
| 185 heap.Grow(memory.Pass(), block_size); |
| 186 |
| 187 // Free list should be empty. |
| 188 EXPECT_EQ(0u, heap.GetFreeListSize()); |
| 189 |
| 190 heap.ReleaseFreeMemory(); |
| 191 |
| 192 // Size should still match |block_size|. |
| 193 EXPECT_EQ(block_size, heap.GetSize()); |
| 194 |
| 195 heap.MergeIntoFreeList(span.Pass()); |
| 196 heap.ReleaseFreeMemory(); |
| 197 |
| 198 // Memory should have been released. |
| 199 EXPECT_EQ(0u, heap.GetSize()); |
| 200 EXPECT_EQ(0u, heap.GetFreeListSize()); |
| 201 } |
| 202 |
| 203 TEST(DiscardableSharedMemoryHeapTest, ReleasePurgedMemory) { |
| 204 size_t block_size = base::GetPageSize(); |
| 205 DiscardableSharedMemoryHeap heap(block_size); |
| 206 |
168 scoped_ptr<base::DiscardableSharedMemory> memory( | 207 scoped_ptr<base::DiscardableSharedMemory> memory( |
169 new base::DiscardableSharedMemory); | 208 new base::DiscardableSharedMemory); |
170 ASSERT_TRUE(memory->CreateAndMap(block_size)); | 209 ASSERT_TRUE(memory->CreateAndMap(block_size)); |
171 scoped_ptr<DiscardableSharedMemoryHeap::Span> span = | 210 scoped_ptr<DiscardableSharedMemoryHeap::Span> span = |
172 heap.Grow(memory.Pass(), block_size); | 211 heap.Grow(memory.Pass(), block_size); |
173 | 212 |
174 // Unlock memory so it can be purged. | 213 // Unlock memory so it can be purged. |
175 span->shared_memory()->Unlock(0, 0); | 214 span->shared_memory()->Unlock(0, 0); |
176 | 215 |
177 // Purge and release shared memory. | 216 // Purge and release shared memory. |
178 bool rv = span->shared_memory()->Purge(base::Time::Now()); | 217 bool rv = span->shared_memory()->Purge(base::Time::Now()); |
179 EXPECT_TRUE(rv); | 218 EXPECT_TRUE(rv); |
180 heap.ReleaseFreeMemory(); | 219 heap.ReleasePurgedMemory(); |
181 | 220 |
182 // Shared memory backing for |span| should be gone. | 221 // Shared memory backing for |span| should be gone. |
183 EXPECT_FALSE(span->shared_memory()); | 222 EXPECT_FALSE(span->shared_memory()); |
| 223 |
| 224 // Size should be 0. |
| 225 EXPECT_EQ(0u, heap.GetSize()); |
184 } | 226 } |
185 | 227 |
186 } // namespace | 228 } // namespace |
187 } // namespace content | 229 } // namespace content |
OLD | NEW |