]>
Commit | Line | Data |
---|---|---|
a8e16298 TL |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | ||
4 | #include <iostream> | |
5 | #include <gtest/gtest.h> | |
6 | ||
7 | #include "os/bluestore/fastbmap_allocator_impl.h" | |
8 | ||
9 | class TestAllocatorLevel01 : public AllocatorLevel01Loose | |
10 | { | |
11 | public: | |
12 | void init(uint64_t capacity, uint64_t alloc_unit) | |
13 | { | |
14 | _init(capacity, alloc_unit); | |
15 | } | |
16 | interval_t allocate_l1_cont(uint64_t length, uint64_t min_length, | |
17 | uint64_t pos_start, uint64_t pos_end) | |
18 | { | |
19 | return _allocate_l1_contiguous(length, min_length, 0, pos_start, pos_end); | |
20 | } | |
21 | void free_l1(const interval_t& r) | |
22 | { | |
23 | _free_l1(r.offset, r.length); | |
24 | } | |
25 | }; | |
26 | ||
27 | class TestAllocatorLevel02 : public AllocatorLevel02<AllocatorLevel01Loose> | |
28 | { | |
29 | public: | |
30 | void init(uint64_t capacity, uint64_t alloc_unit) | |
31 | { | |
32 | _init(capacity, alloc_unit); | |
33 | } | |
34 | void allocate_l2(uint64_t length, uint64_t min_length, | |
35 | uint64_t* allocated0, | |
36 | interval_vector_t* res) | |
37 | { | |
38 | uint64_t allocated = 0; | |
39 | uint64_t hint = 0; // trigger internal l2 hint support | |
40 | _allocate_l2(length, min_length, 0, hint, &allocated, res); | |
41 | *allocated0 += allocated; | |
42 | } | |
43 | void free_l2(const interval_vector_t& r) | |
44 | { | |
45 | _free_l2(r); | |
46 | } | |
47 | }; | |
48 | ||
49 | const uint64_t _1m = 1024 * 1024; | |
50 | const uint64_t _2m = 2 * 1024 * 1024; | |
51 | ||
52 | TEST(TestAllocatorLevel01, test_l1) | |
53 | { | |
54 | TestAllocatorLevel01 al1; | |
55 | uint64_t num_l1_entries = 3 * 256; | |
56 | uint64_t capacity = num_l1_entries * 512 * 4096; | |
57 | al1.init(capacity, 0x1000); | |
58 | ASSERT_EQ(capacity, al1.debug_get_free()); | |
59 | ||
60 | auto i1 = al1.allocate_l1_cont(0x1000, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
61 | ASSERT_EQ(i1.offset, 0u); |
62 | ASSERT_EQ(i1.length, 0x1000u); | |
a8e16298 TL |
63 | ASSERT_EQ(capacity - 0x1000, al1.debug_get_free()); |
64 | ||
65 | auto i2 = al1.allocate_l1_cont(0x1000, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
66 | ASSERT_EQ(i2.offset, 0x1000u); |
67 | ASSERT_EQ(i2.length, 0x1000u); | |
a8e16298 TL |
68 | al1.free_l1(i2); |
69 | al1.free_l1(i1); | |
70 | i1 = al1.allocate_l1_cont(0x1000, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
71 | ASSERT_EQ(i1.offset, 0u); |
72 | ASSERT_EQ(i1.length, 0x1000u); | |
a8e16298 | 73 | i2 = al1.allocate_l1_cont(0x1000, 0x1000, 0, num_l1_entries); |
11fdf7f2 TL |
74 | ASSERT_EQ(i2.offset, 0x1000u); |
75 | ASSERT_EQ(i2.length, 0x1000u); | |
a8e16298 TL |
76 | al1.free_l1(i1); |
77 | al1.free_l1(i2); | |
78 | ||
79 | i1 = al1.allocate_l1_cont(0x2000, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
80 | ASSERT_EQ(i1.offset, 0u); |
81 | ASSERT_EQ(i1.length, 0x2000u); | |
a8e16298 TL |
82 | |
83 | i2 = al1.allocate_l1_cont(0x3000, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
84 | ASSERT_EQ(i2.offset, 0x2000u); |
85 | ASSERT_EQ(i2.length, 0x3000u); | |
a8e16298 TL |
86 | |
87 | al1.free_l1(i1); | |
88 | al1.free_l1(i2); | |
89 | ||
90 | i1 = al1.allocate_l1_cont(0x2000, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
91 | ASSERT_EQ(i1.offset, 0u); |
92 | ASSERT_EQ(i1.length, 0x2000u); | |
a8e16298 TL |
93 | |
94 | i2 = al1.allocate_l1_cont(2 * 1024 * 1024, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
95 | ASSERT_EQ(i2.offset, 2u * 1024u * 1024u); |
96 | ASSERT_EQ(i2.length, 2u * 1024u * 1024u); | |
a8e16298 TL |
97 | |
98 | al1.free_l1(i1); | |
99 | i1 = al1.allocate_l1_cont(1024 * 1024, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
100 | ASSERT_EQ(i1.offset, 0u); |
101 | ASSERT_EQ(i1.length, 1024u * 1024u); | |
a8e16298 TL |
102 | |
103 | auto i3 = al1.allocate_l1_cont(1024 * 1024 + 0x1000, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
104 | ASSERT_EQ(i3.offset, 2u * 2u * 1024u * 1024u); |
105 | ASSERT_EQ(i3.length, 1024u * 1024u + 0x1000u); | |
a8e16298 TL |
106 | |
107 | // here we have the following layout: | |
108 | // Alloc: 0~1M, 2M~2M, 4M~1M+4K | |
109 | // Free: 1M~1M, 4M+4K ~ 2M-4K, 6M ~... | |
110 | // | |
111 | auto i4 = al1.allocate_l1_cont(1024 * 1024, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
112 | ASSERT_EQ(1 * 1024 * 1024u, i4.offset); |
113 | ASSERT_EQ(1024 * 1024u, i4.length); | |
a8e16298 TL |
114 | al1.free_l1(i4); |
115 | ||
116 | i4 = al1.allocate_l1_cont(1024 * 1024 - 0x1000, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
117 | ASSERT_EQ(i4.offset, 5u * 1024u * 1024u + 0x1000u); |
118 | ASSERT_EQ(i4.length, 1024u * 1024u - 0x1000u); | |
a8e16298 TL |
119 | al1.free_l1(i4); |
120 | ||
121 | i4 = al1.allocate_l1_cont(1024 * 1024 + 0x1000, 0x1000, 0, num_l1_entries); | |
11fdf7f2 | 122 | ASSERT_EQ(i4.offset, 6u * 1024u * 1024u); |
a8e16298 | 123 | //ASSERT_EQ(i4.offset, 5 * 1024 * 1024 + 0x1000); |
11fdf7f2 | 124 | ASSERT_EQ(i4.length, 1024u * 1024u + 0x1000u); |
a8e16298 TL |
125 | |
126 | al1.free_l1(i1); | |
127 | al1.free_l1(i2); | |
128 | al1.free_l1(i3); | |
129 | al1.free_l1(i4); | |
130 | ||
131 | i1 = al1.allocate_l1_cont(1024 * 1024, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
132 | ASSERT_EQ(i1.offset, 0u); |
133 | ASSERT_EQ(i1.length, 1024u * 1024u); | |
a8e16298 TL |
134 | |
135 | i2 = al1.allocate_l1_cont(1024 * 1024, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
136 | ASSERT_EQ(i2.offset, 1u * 1024u * 1024u); |
137 | ASSERT_EQ(i2.length, 1024u * 1024u); | |
a8e16298 TL |
138 | |
139 | i3 = al1.allocate_l1_cont(512 * 1024, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
140 | ASSERT_EQ(i3.offset, 2u * 1024u * 1024u); |
141 | ASSERT_EQ(i3.length, 512u * 1024u); | |
a8e16298 TL |
142 | |
143 | i4 = al1.allocate_l1_cont(1536 * 1024, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
144 | ASSERT_EQ(i4.offset, (2u * 1024u + 512u) * 1024u); |
145 | ASSERT_EQ(i4.length, 1536u * 1024u); | |
a8e16298 TL |
146 | // making a hole 1.5 Mb length |
147 | al1.free_l1(i2); | |
148 | al1.free_l1(i3); | |
149 | // and trying to fill it | |
150 | i2 = al1.allocate_l1_cont(1536 * 1024, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
151 | ASSERT_EQ(i2.offset, 1024u * 1024u); |
152 | ASSERT_EQ(i2.length, 1536u * 1024u); | |
a8e16298 TL |
153 | |
154 | al1.free_l1(i2); | |
155 | // and trying to fill it partially | |
156 | i2 = al1.allocate_l1_cont(1528 * 1024, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
157 | ASSERT_EQ(i2.offset, 1024u * 1024u); |
158 | ASSERT_EQ(i2.length, 1528u * 1024u); | |
a8e16298 TL |
159 | |
160 | i3 = al1.allocate_l1_cont(8 * 1024, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
161 | ASSERT_EQ(i3.offset, 2552u * 1024u); |
162 | ASSERT_EQ(i3.length, 8u * 1024u); | |
a8e16298 TL |
163 | |
164 | al1.free_l1(i2); | |
165 | // here we have the following layout: | |
166 | // Alloc: 0~1M, 2552K~8K, num_l1_entries0K~1.5M | |
167 | // Free: 1M~1528K, 4M ~... | |
168 | // | |
169 | i2 = al1.allocate_l1_cont(1536 * 1024, 0x1000, 0, num_l1_entries); | |
11fdf7f2 TL |
170 | ASSERT_EQ(i2.offset, 4u * 1024u * 1024u); |
171 | ASSERT_EQ(i2.length, 1536u * 1024u); | |
a8e16298 TL |
172 | |
173 | al1.free_l1(i1); | |
174 | al1.free_l1(i2); | |
175 | al1.free_l1(i3); | |
176 | al1.free_l1(i4); | |
177 | ASSERT_EQ(capacity, al1.debug_get_free()); | |
178 | ||
179 | for (uint64_t i = 0; i < capacity; i += _2m) { | |
180 | i1 = al1.allocate_l1_cont(_2m, _2m, 0, num_l1_entries); | |
181 | ASSERT_EQ(i1.offset, i); | |
182 | ASSERT_EQ(i1.length, _2m); | |
183 | } | |
11fdf7f2 | 184 | ASSERT_EQ(0u, al1.debug_get_free()); |
a8e16298 | 185 | i2 = al1.allocate_l1_cont(_2m, _2m, 0, num_l1_entries); |
11fdf7f2 TL |
186 | ASSERT_EQ(i2.length, 0u); |
187 | ASSERT_EQ(0u, al1.debug_get_free()); | |
a8e16298 TL |
188 | |
189 | al1.free_l1(i1); | |
190 | i2 = al1.allocate_l1_cont(_2m, _2m, 0, num_l1_entries); | |
191 | ASSERT_EQ(i2, i1); | |
192 | al1.free_l1(i2); | |
193 | i2 = al1.allocate_l1_cont(_1m, _1m, 0, num_l1_entries); | |
194 | ASSERT_EQ(i2.offset, i1.offset); | |
195 | ASSERT_EQ(i2.length, _1m); | |
196 | ||
197 | i3 = al1.allocate_l1_cont(_2m, _2m, 0, num_l1_entries); | |
11fdf7f2 | 198 | ASSERT_EQ(i3.length, 0u); |
a8e16298 TL |
199 | |
200 | i3 = al1.allocate_l1_cont(_2m, _1m, 0, num_l1_entries); | |
201 | ASSERT_EQ(i3.length, _1m); | |
202 | ||
203 | i4 = al1.allocate_l1_cont(_2m, _1m, 0, num_l1_entries); | |
11fdf7f2 | 204 | ASSERT_EQ(i4.length, 0u); |
a8e16298 TL |
205 | |
206 | al1.free_l1(i2); | |
207 | i2 = al1.allocate_l1_cont(_2m, _2m, 0, num_l1_entries); | |
11fdf7f2 | 208 | ASSERT_EQ(i2.length, 0u); |
a8e16298 TL |
209 | |
210 | i2 = al1.allocate_l1_cont(_2m, 0x1000, 0, num_l1_entries); | |
211 | ASSERT_EQ(i2.length, _1m); | |
212 | ||
213 | al1.free_l1(i2); | |
214 | al1.free_l1(i3); | |
215 | ASSERT_EQ(_2m, al1.debug_get_free()); | |
216 | ||
217 | i1 = al1.allocate_l1_cont(_2m - 3 * 0x1000, 0x1000, 0, num_l1_entries); | |
218 | i2 = al1.allocate_l1_cont(0x1000, 0x1000, 0, num_l1_entries); | |
219 | i3 = al1.allocate_l1_cont(0x1000, 0x1000, 0, num_l1_entries); | |
220 | i4 = al1.allocate_l1_cont(0x1000, 0x1000, 0, num_l1_entries); | |
11fdf7f2 | 221 | ASSERT_EQ(0u, al1.debug_get_free()); |
a8e16298 TL |
222 | |
223 | al1.free_l1(i2); | |
224 | al1.free_l1(i4); | |
225 | ||
226 | i2 = al1.allocate_l1_cont(0x4000, 0x2000, 0, num_l1_entries); | |
11fdf7f2 | 227 | ASSERT_EQ(i2.length, 0u); |
a8e16298 | 228 | i2 = al1.allocate_l1_cont(0x4000, 0x1000, 0, num_l1_entries); |
11fdf7f2 | 229 | ASSERT_EQ(i2.length, 0x1000u); |
a8e16298 TL |
230 | |
231 | al1.free_l1(i3); | |
232 | i3 = al1.allocate_l1_cont(0x6000, 0x3000, 0, num_l1_entries); | |
11fdf7f2 | 233 | ASSERT_EQ(i3.length, 0u); |
a8e16298 | 234 | i3 = al1.allocate_l1_cont(0x6000, 0x1000, 0, num_l1_entries); |
11fdf7f2 TL |
235 | ASSERT_EQ(i3.length, 0x2000u); |
236 | ASSERT_EQ(0u, al1.debug_get_free()); | |
a8e16298 TL |
237 | |
238 | std::cout << "Done L1" << std::endl; | |
239 | } | |
240 | ||
241 | TEST(TestAllocatorLevel01, test_l2) | |
242 | { | |
243 | TestAllocatorLevel02 al2; | |
244 | uint64_t num_l2_entries = 64;// *512; | |
245 | uint64_t capacity = num_l2_entries * 256 * 512 * 4096; | |
246 | al2.init(capacity, 0x1000); | |
247 | std::cout << "Init L2" << std::endl; | |
248 | ||
249 | uint64_t allocated1 = 0; | |
250 | interval_vector_t a1; | |
251 | al2.allocate_l2(0x2000, 0x2000, &allocated1, &a1); | |
11fdf7f2 TL |
252 | ASSERT_EQ(allocated1, 0x2000u); |
253 | ASSERT_EQ(a1[0].offset, 0u); | |
254 | ASSERT_EQ(a1[0].length, 0x2000u); | |
a8e16298 TL |
255 | |
256 | // limit query range in debug_get_free for the sake of performance | |
11fdf7f2 TL |
257 | ASSERT_EQ(0x2000u, al2.debug_get_allocated(0, 1)); |
258 | ASSERT_EQ(0u, al2.debug_get_allocated(1, 2)); | |
a8e16298 TL |
259 | |
260 | uint64_t allocated2 = 0; | |
261 | interval_vector_t a2; | |
262 | al2.allocate_l2(0x2000, 0x2000, &allocated2, &a2); | |
11fdf7f2 TL |
263 | ASSERT_EQ(allocated2, 0x2000u); |
264 | ASSERT_EQ(a2[0].offset, 0x2000u); | |
265 | ASSERT_EQ(a2[0].length, 0x2000u); | |
a8e16298 | 266 | // limit query range in debug_get_free for the sake of performance |
11fdf7f2 TL |
267 | ASSERT_EQ(0x4000u, al2.debug_get_allocated(0, 1)); |
268 | ASSERT_EQ(0u, al2.debug_get_allocated(1, 2)); | |
a8e16298 TL |
269 | |
270 | al2.free_l2(a1); | |
271 | ||
272 | allocated2 = 0; | |
273 | a2.clear(); | |
274 | al2.allocate_l2(0x1000, 0x1000, &allocated2, &a2); | |
11fdf7f2 TL |
275 | ASSERT_EQ(allocated2, 0x1000u); |
276 | ASSERT_EQ(a2[0].offset, 0x0000u); | |
277 | ASSERT_EQ(a2[0].length, 0x1000u); | |
a8e16298 | 278 | // limit query range in debug_get_free for the sake of performance |
11fdf7f2 TL |
279 | ASSERT_EQ(0x3000u, al2.debug_get_allocated(0, 1)); |
280 | ASSERT_EQ(0u, al2.debug_get_allocated(1, 2)); | |
a8e16298 TL |
281 | |
282 | uint64_t allocated3 = 0; | |
283 | interval_vector_t a3; | |
284 | al2.allocate_l2(0x2000, 0x1000, &allocated3, &a3); | |
11fdf7f2 TL |
285 | ASSERT_EQ(allocated3, 0x2000u); |
286 | ASSERT_EQ(a3.size(), 2u); | |
287 | ASSERT_EQ(a3[0].offset, 0x1000u); | |
288 | ASSERT_EQ(a3[0].length, 0x1000u); | |
289 | ASSERT_EQ(a3[1].offset, 0x4000u); | |
290 | ASSERT_EQ(a3[1].length, 0x1000u); | |
a8e16298 | 291 | // limit query range in debug_get_free for the sake of performance |
11fdf7f2 TL |
292 | ASSERT_EQ(0x5000u, al2.debug_get_allocated(0, 1)); |
293 | ASSERT_EQ(0u, al2.debug_get_allocated(1, 2)); | |
a8e16298 TL |
294 | { |
295 | interval_vector_t r; | |
296 | r.emplace_back(0x0, 0x5000); | |
297 | al2.free_l2(r); | |
298 | } | |
299 | ||
300 | a3.clear(); | |
301 | allocated3 = 0; | |
302 | al2.allocate_l2(_1m, _1m, &allocated3, &a3); | |
11fdf7f2 TL |
303 | ASSERT_EQ(a3.size(), 1u); |
304 | ASSERT_EQ(a3[0].offset, 0u); | |
a8e16298 TL |
305 | ASSERT_EQ(a3[0].length, _1m); |
306 | ||
307 | al2.free_l2(a3); | |
308 | ||
309 | a3.clear(); | |
310 | allocated3 = 0; | |
311 | al2.allocate_l2(4 * _1m, _1m, &allocated3, &a3); | |
11fdf7f2 TL |
312 | ASSERT_EQ(a3.size(), 1u); |
313 | ASSERT_EQ(a3[0].offset, 0u); | |
a8e16298 TL |
314 | ASSERT_EQ(a3[0].length, 4 * _1m); |
315 | ||
316 | al2.free_l2(a3); | |
317 | ||
318 | #ifndef _DEBUG | |
319 | for (uint64_t i = 0; i < capacity; i += 0x1000) { | |
320 | uint64_t allocated4 = 0; | |
321 | interval_vector_t a4; | |
322 | al2.allocate_l2(0x1000, 0x1000, &allocated4, &a4); | |
11fdf7f2 | 323 | ASSERT_EQ(a4.size(), 1u); |
a8e16298 | 324 | ASSERT_EQ(a4[0].offset, i); |
11fdf7f2 | 325 | ASSERT_EQ(a4[0].length, 0x1000u); |
a8e16298 TL |
326 | if (0 == (i % (1 * 1024 * _1m))) { |
327 | std::cout << "alloc1 " << i / 1024 / 1024 << " mb of " | |
328 | << capacity / 1024 / 1024 << std::endl; | |
329 | } | |
330 | } | |
331 | #else | |
332 | for (uint64_t i = 0; i < capacity; i += _2m) { | |
333 | uint64_t allocated4 = 0; | |
334 | interval_vector_t a4; | |
335 | al2.allocate_l2(_2m, _2m, &allocated4, &a4); | |
336 | ASSERT_EQ(a4.size(), 1); | |
337 | ASSERT_EQ(a4[0].offset, i); | |
338 | ASSERT_EQ(a4[0].length, _2m); | |
339 | if (0 == (i % (1 * 1024 * _1m))) { | |
340 | std::cout << "alloc1 " << i / 1024 / 1024 << " mb of " | |
341 | << capacity / 1024 / 1024 << std::endl; | |
342 | } | |
343 | } | |
344 | #endif | |
345 | ||
11fdf7f2 | 346 | ASSERT_EQ(0u, al2.debug_get_free()); |
a8e16298 TL |
347 | for (uint64_t i = 0; i < capacity; i += _1m) { |
348 | interval_vector_t r; | |
349 | r.emplace_back(i, _1m); | |
350 | al2.free_l2(r); | |
351 | if (0 == (i % (1 * 1024 * _1m))) { | |
352 | std::cout << "free1 " << i / 1024 / 1024 << " mb of " | |
353 | << capacity / 1024 / 1024 << std::endl; | |
354 | } | |
355 | } | |
356 | ASSERT_EQ(capacity, al2.debug_get_free()); | |
357 | ||
358 | for (uint64_t i = 0; i < capacity; i += _1m) { | |
359 | uint64_t allocated4 = 0; | |
360 | interval_vector_t a4; | |
361 | al2.allocate_l2(_1m, _1m, &allocated4, &a4); | |
11fdf7f2 | 362 | ASSERT_EQ(a4.size(), 1u); |
a8e16298 TL |
363 | ASSERT_EQ(allocated4, _1m); |
364 | ASSERT_EQ(a4[0].offset, i); | |
365 | ASSERT_EQ(a4[0].length, _1m); | |
366 | if (0 == (i % (1 * 1024 * _1m))) { | |
367 | std::cout << "alloc2 " << i / 1024 / 1024 << " mb of " | |
368 | << capacity / 1024 / 1024 << std::endl; | |
369 | } | |
370 | } | |
11fdf7f2 | 371 | ASSERT_EQ(0u, al2.debug_get_free()); |
a8e16298 TL |
372 | uint64_t allocated4 = 0; |
373 | interval_vector_t a4; | |
374 | al2.allocate_l2(_1m, _1m, &allocated4, &a4); | |
11fdf7f2 | 375 | ASSERT_EQ(a4.size(), 0u); |
a8e16298 | 376 | al2.allocate_l2(0x1000, 0x1000, &allocated4, &a4); |
11fdf7f2 | 377 | ASSERT_EQ(a4.size(), 0u); |
a8e16298 TL |
378 | |
379 | for (uint64_t i = 0; i < capacity; i += 0x2000) { | |
380 | interval_vector_t r; | |
381 | r.emplace_back(i, 0x1000); | |
382 | al2.free_l2(r); | |
383 | if (0 == (i % (1 * 1024 * _1m))) { | |
384 | std::cout << "free2 " << i / 1024 / 1024 << " mb of " | |
385 | << capacity / 1024 / 1024 << std::endl; | |
386 | } | |
387 | } | |
388 | ASSERT_EQ(capacity / 2, al2.debug_get_free()); | |
389 | ||
390 | // unable to allocate due to fragmentation | |
391 | al2.allocate_l2(_1m, _1m, &allocated4, &a4); | |
11fdf7f2 | 392 | ASSERT_EQ(a4.size(), 0u); |
a8e16298 TL |
393 | |
394 | for (uint64_t i = 0; i < capacity; i += 2 * _1m) { | |
395 | a4.clear(); | |
396 | allocated4 = 0; | |
397 | al2.allocate_l2(_1m, 0x1000, &allocated4, &a4); | |
398 | ASSERT_EQ(a4.size(), _1m / 0x1000); | |
399 | ASSERT_EQ(allocated4, _1m); | |
400 | ASSERT_EQ(a4[0].offset, i); | |
11fdf7f2 | 401 | ASSERT_EQ(a4[0].length, 0x1000u); |
a8e16298 TL |
402 | if (0 == (i % (1 * 1024 * _1m))) { |
403 | std::cout << "alloc3 " << i / 1024 / 1024 << " mb of " | |
404 | << capacity / 1024 / 1024 << std::endl; | |
405 | } | |
406 | } | |
11fdf7f2 | 407 | ASSERT_EQ(0u, al2.debug_get_free()); |
a8e16298 TL |
408 | |
409 | std::cout << "Done L2" << std::endl; | |
410 | } | |
411 | ||
412 | TEST(TestAllocatorLevel01, test_l2_huge) | |
413 | { | |
414 | TestAllocatorLevel02 al2; | |
415 | uint64_t num_l2_entries = 4 * 512; | |
416 | uint64_t capacity = num_l2_entries * 256 * 512 * 4096; // 1 TB | |
417 | al2.init(capacity, 0x1000); | |
418 | std::cout << "Init L2 Huge" << std::endl; | |
419 | ||
420 | for (uint64_t i = 0; i < capacity; i += _1m) { | |
421 | uint64_t allocated4 = 0; | |
422 | interval_vector_t a4; | |
423 | al2.allocate_l2(0x1000, 0x1000, &allocated4, &a4); | |
11fdf7f2 TL |
424 | ASSERT_EQ(a4.size(), 1u); |
425 | ASSERT_EQ(allocated4, 0x1000u); | |
a8e16298 | 426 | ASSERT_EQ(a4[0].offset, i); |
11fdf7f2 | 427 | ASSERT_EQ(a4[0].length, 0x1000u); |
a8e16298 TL |
428 | |
429 | allocated4 = 0; | |
430 | a4.clear(); | |
431 | al2.allocate_l2(_1m - 0x1000, 0x1000, &allocated4, &a4); | |
11fdf7f2 | 432 | ASSERT_EQ(a4.size(), 1u); |
a8e16298 TL |
433 | ASSERT_EQ(allocated4, _1m - 0x1000); |
434 | ASSERT_EQ(a4[0].offset, i + 0x1000); | |
435 | ASSERT_EQ(a4[0].length, _1m - 0x1000); | |
436 | if (0 == (i % (1 * 1024 * _1m))) { | |
437 | std::cout << "allocH " << i / 1024 / 1024 << " mb of " | |
438 | << capacity / 1024 / 1024 << std::endl; | |
439 | } | |
440 | } | |
441 | for (uint64_t i = 0; i < capacity; i += _1m) { | |
442 | interval_vector_t a4; | |
443 | a4.emplace_back(i, 0x1000); | |
444 | al2.free_l2(a4); | |
445 | if (0 == (i % (1 * 1024 * _1m))) { | |
446 | std::cout << "freeH1 " << i / 1024 / 1024 << " mb of " | |
447 | << capacity / 1024 / 1024 << std::endl; | |
448 | } | |
449 | } | |
450 | { | |
451 | std::cout << "Try" << std::endl; | |
452 | time_t t = time(NULL); | |
453 | for (int i = 0; i < 10; ++i) { | |
454 | uint64_t allocated = 0; | |
455 | interval_vector_t a; | |
456 | al2.allocate_l2(0x2000, 0x2000, &allocated, &a); | |
11fdf7f2 | 457 | ASSERT_EQ(a.size(), 0u); |
a8e16298 TL |
458 | } |
459 | std::cout << "End try in " << time(NULL) - t << " seconds" << std::endl; | |
460 | } | |
461 | { | |
462 | std::cout << "Try" << std::endl; | |
463 | time_t t = time(NULL); | |
464 | for (int i = 0; i < 10; ++i) { | |
465 | uint64_t allocated = 0; | |
466 | interval_vector_t a; | |
467 | al2.allocate_l2(_2m, _2m, &allocated, &a); | |
11fdf7f2 | 468 | ASSERT_EQ(a.size(), 0u); |
a8e16298 TL |
469 | } |
470 | std::cout << "End try in " << time(NULL) - t << " seconds" << std::endl; | |
471 | } | |
472 | ||
473 | ASSERT_EQ((capacity / _1m) * 0x1000, al2.debug_get_free()); | |
474 | ||
475 | std::cout << "Done L2 Huge" << std::endl; | |
476 | } | |
477 | ||
478 | TEST(TestAllocatorLevel01, test_l2_unaligned) | |
479 | { | |
480 | { | |
481 | TestAllocatorLevel02 al2; | |
482 | uint64_t num_l2_entries = 3; | |
483 | uint64_t capacity = num_l2_entries * 256 * 512 * 4096; // 3x512 MB | |
484 | al2.init(capacity, 0x1000); | |
485 | std::cout << "Init L2 Unaligned" << std::endl; | |
486 | ||
487 | for (uint64_t i = 0; i < capacity; i += _1m / 2) { | |
488 | uint64_t allocated4 = 0; | |
489 | interval_vector_t a4; | |
490 | al2.allocate_l2(_1m / 2, _1m / 2, &allocated4, &a4); | |
11fdf7f2 | 491 | ASSERT_EQ(a4.size(), 1u); |
a8e16298 TL |
492 | ASSERT_EQ(allocated4, _1m / 2); |
493 | ASSERT_EQ(a4[0].offset, i); | |
494 | ASSERT_EQ(a4[0].length, _1m / 2); | |
495 | if (0 == (i % (1 * 1024 * _1m))) { | |
496 | std::cout << "allocU " << i / 1024 / 1024 << " mb of " | |
497 | << capacity / 1024 / 1024 << std::endl; | |
498 | } | |
499 | } | |
11fdf7f2 | 500 | ASSERT_EQ(0u, al2.debug_get_free()); |
a8e16298 TL |
501 | { |
502 | // no space to allocate | |
503 | uint64_t allocated4 = 0; | |
504 | interval_vector_t a4; | |
505 | al2.allocate_l2(0x1000, 0x1000, &allocated4, &a4); | |
11fdf7f2 | 506 | ASSERT_EQ(a4.size(), 0u); |
a8e16298 TL |
507 | } |
508 | } | |
509 | { | |
510 | TestAllocatorLevel02 al2; | |
511 | uint64_t capacity = 500 * 512 * 4096; // 500x2 MB | |
512 | al2.init(capacity, 0x1000); | |
513 | std::cout << ("Init L2 Unaligned2\n"); | |
514 | for (uint64_t i = 0; i < capacity; i += _1m / 2) { | |
515 | uint64_t allocated4 = 0; | |
516 | interval_vector_t a4; | |
517 | al2.allocate_l2(_1m / 2, _1m / 2, &allocated4, &a4); | |
11fdf7f2 | 518 | ASSERT_EQ(a4.size(), 1u); |
a8e16298 TL |
519 | ASSERT_EQ(allocated4, _1m / 2); |
520 | ASSERT_EQ(a4[0].offset, i); | |
521 | ASSERT_EQ(a4[0].length, _1m / 2); | |
522 | if (0 == (i % (1 * 1024 * _1m))) { | |
523 | std::cout << "allocU2 " << i / 1024 / 1024 << " mb of " | |
524 | << capacity / 1024 / 1024 << std::endl; | |
525 | } | |
526 | } | |
11fdf7f2 | 527 | ASSERT_EQ(0u, al2.debug_get_free()); |
a8e16298 TL |
528 | { |
529 | // no space to allocate | |
530 | uint64_t allocated4 = 0; | |
531 | interval_vector_t a4; | |
532 | al2.allocate_l2(0x1000, 0x1000, &allocated4, &a4); | |
11fdf7f2 | 533 | ASSERT_EQ(a4.size(), 0u); |
a8e16298 TL |
534 | } |
535 | } | |
536 | ||
537 | { | |
538 | TestAllocatorLevel02 al2; | |
539 | uint64_t capacity = 100 * 512 * 4096 + 127 * 4096; | |
540 | al2.init(capacity, 0x1000); | |
541 | std::cout << "Init L2 Unaligned2" << std::endl; | |
542 | for (uint64_t i = 0; i < capacity; i += 0x1000) { | |
543 | uint64_t allocated4 = 0; | |
544 | interval_vector_t a4; | |
545 | al2.allocate_l2(0x1000, 0x1000, &allocated4, &a4); | |
11fdf7f2 TL |
546 | ASSERT_EQ(a4.size(), 1u); |
547 | ASSERT_EQ(allocated4, 0x1000u); | |
a8e16298 | 548 | ASSERT_EQ(a4[0].offset, i); |
11fdf7f2 | 549 | ASSERT_EQ(a4[0].length, 0x1000u); |
a8e16298 | 550 | } |
11fdf7f2 | 551 | ASSERT_EQ(0u, al2.debug_get_free()); |
a8e16298 TL |
552 | { |
553 | // no space to allocate | |
554 | uint64_t allocated4 = 0; | |
555 | interval_vector_t a4; | |
556 | al2.allocate_l2(0x1000, 0x1000, &allocated4, &a4); | |
11fdf7f2 | 557 | ASSERT_EQ(a4.size(), 0u); |
a8e16298 TL |
558 | } |
559 | } | |
560 | { | |
561 | TestAllocatorLevel02 al2; | |
562 | uint64_t capacity = 3 * 4096; | |
563 | al2.init(capacity, 0x1000); | |
564 | std::cout << "Init L2 Unaligned2" << std::endl; | |
565 | for (uint64_t i = 0; i < capacity; i += 0x1000) { | |
566 | uint64_t allocated4 = 0; | |
567 | interval_vector_t a4; | |
568 | al2.allocate_l2(0x1000, 0x1000, &allocated4, &a4); | |
11fdf7f2 TL |
569 | ASSERT_EQ(a4.size(), 1u); |
570 | ASSERT_EQ(allocated4, 0x1000u); | |
a8e16298 | 571 | ASSERT_EQ(a4[0].offset, i); |
11fdf7f2 | 572 | ASSERT_EQ(a4[0].length, 0x1000u); |
a8e16298 | 573 | } |
11fdf7f2 | 574 | ASSERT_EQ(0u, al2.debug_get_free()); |
a8e16298 TL |
575 | { |
576 | // no space to allocate | |
577 | uint64_t allocated4 = 0; | |
578 | interval_vector_t a4; | |
579 | al2.allocate_l2(0x1000, 0x1000, &allocated4, &a4); | |
11fdf7f2 | 580 | ASSERT_EQ(a4.size(), 0u); |
a8e16298 TL |
581 | } |
582 | } | |
583 | ||
584 | std::cout << "Done L2 Unaligned" << std::endl; | |
585 | } | |
586 | ||
587 | TEST(TestAllocatorLevel01, test_l2_contiguous_alignment) | |
588 | { | |
589 | { | |
590 | TestAllocatorLevel02 al2; | |
591 | uint64_t num_l2_entries = 3; | |
592 | uint64_t capacity = num_l2_entries * 256 * 512 * 4096; // 3x512 MB | |
593 | uint64_t num_chunks = capacity / 4096; | |
594 | al2.init(capacity, 4096); | |
595 | std::cout << "Init L2 cont aligned" << std::endl; | |
596 | ||
597 | std::map<size_t, size_t> bins_overall; | |
598 | al2.collect_stats(bins_overall); | |
599 | ASSERT_EQ(bins_overall.size(), 1u); | |
600 | // std::cout<<bins_overall.begin()->first << std::endl; | |
601 | ASSERT_EQ(bins_overall[cbits(num_chunks) - 1], 1u); | |
602 | ||
603 | for (uint64_t i = 0; i < capacity / 2; i += _1m) { | |
604 | uint64_t allocated4 = 0; | |
605 | interval_vector_t a4; | |
606 | al2.allocate_l2(_1m, _1m, &allocated4, &a4); | |
11fdf7f2 | 607 | ASSERT_EQ(a4.size(), 1u); |
a8e16298 TL |
608 | ASSERT_EQ(allocated4, _1m); |
609 | ASSERT_EQ(a4[0].offset, i); | |
610 | ASSERT_EQ(a4[0].length, _1m); | |
611 | } | |
612 | ASSERT_EQ(capacity / 2, al2.debug_get_free()); | |
613 | ||
614 | bins_overall.clear(); | |
615 | al2.collect_stats(bins_overall); | |
616 | ASSERT_EQ(bins_overall.size(), 1u); | |
617 | ASSERT_EQ(bins_overall[cbits(num_chunks / 2) - 1], 1u); | |
618 | ||
619 | { | |
620 | size_t to_release = 2 * _1m + 0x1000; | |
621 | // release 2M + 4K at the beginning | |
622 | interval_vector_t r; | |
623 | r.emplace_back(0, to_release); | |
624 | al2.free_l2(r); | |
625 | bins_overall.clear(); | |
626 | al2.collect_stats(bins_overall); | |
627 | ASSERT_EQ(bins_overall.size(), 2u); | |
628 | ASSERT_EQ(bins_overall[cbits(to_release / 0x1000) - 1], 1u); | |
629 | ASSERT_EQ(bins_overall[cbits(num_chunks / 2) - 1], 1u); | |
630 | } | |
631 | { | |
632 | // allocate 4K within the deallocated range | |
633 | uint64_t allocated4 = 0; | |
634 | interval_vector_t a4; | |
635 | al2.allocate_l2(0x1000, 0x1000, &allocated4, &a4); | |
636 | ASSERT_EQ(a4.size(), 1u); | |
637 | ASSERT_EQ(allocated4, 0x1000u); | |
638 | ASSERT_EQ(a4[0].offset, 0u); | |
639 | ASSERT_EQ(a4[0].length, 0x1000u); | |
640 | bins_overall.clear(); | |
641 | al2.collect_stats(bins_overall); | |
642 | ASSERT_EQ(bins_overall.size(), 2u); | |
643 | ASSERT_EQ(bins_overall[cbits(2 * _1m / 0x1000) - 1], 1u); | |
644 | ASSERT_EQ(bins_overall[cbits(num_chunks / 2) - 1], 1u); | |
645 | } | |
646 | { | |
647 | // allocate 1M - should go to the second 1M chunk | |
648 | uint64_t allocated4 = 0; | |
649 | interval_vector_t a4; | |
650 | al2.allocate_l2(_1m, _1m, &allocated4, &a4); | |
11fdf7f2 | 651 | ASSERT_EQ(a4.size(), 1u); |
a8e16298 TL |
652 | ASSERT_EQ(allocated4, _1m); |
653 | ASSERT_EQ(a4[0].offset, _1m); | |
654 | ASSERT_EQ(a4[0].length, _1m); | |
655 | bins_overall.clear(); | |
656 | al2.collect_stats(bins_overall); | |
657 | ASSERT_EQ(bins_overall.size(), 3u); | |
658 | ASSERT_EQ(bins_overall[0], 1u); | |
659 | ASSERT_EQ(bins_overall[cbits((_1m - 0x1000) / 0x1000) - 1], 1u); | |
660 | ASSERT_EQ(bins_overall[cbits(num_chunks / 2) - 1], 1u); | |
661 | } | |
662 | { | |
663 | // and allocate yet another 8K within the deallocated range | |
664 | uint64_t allocated4 = 0; | |
665 | interval_vector_t a4; | |
666 | al2.allocate_l2(0x2000, 0x1000, &allocated4, &a4); | |
667 | ASSERT_EQ(a4.size(), 1u); | |
668 | ASSERT_EQ(allocated4, 0x2000u); | |
669 | ASSERT_EQ(a4[0].offset, 0x1000u); | |
670 | ASSERT_EQ(a4[0].length, 0x2000u); | |
671 | bins_overall.clear(); | |
672 | al2.collect_stats(bins_overall); | |
673 | ASSERT_EQ(bins_overall[0], 1u); | |
674 | ASSERT_EQ(bins_overall[cbits((_1m - 0x3000) / 0x1000) - 1], 1u); | |
675 | ASSERT_EQ(bins_overall[cbits(num_chunks / 2) - 1], 1u); | |
676 | } | |
677 | { | |
678 | // release just allocated 1M | |
679 | interval_vector_t r; | |
680 | r.emplace_back(_1m, _1m); | |
681 | al2.free_l2(r); | |
682 | bins_overall.clear(); | |
683 | al2.collect_stats(bins_overall); | |
684 | ASSERT_EQ(bins_overall.size(), 2u); | |
685 | ASSERT_EQ(bins_overall[cbits((2 * _1m - 0x3000) / 0x1000) - 1], 1u); | |
686 | ASSERT_EQ(bins_overall[cbits(num_chunks / 2) - 1], 1u); | |
687 | } | |
688 | { | |
689 | // allocate 3M - should go to the second 1M chunk and @capacity/2 | |
690 | uint64_t allocated4 = 0; | |
691 | interval_vector_t a4; | |
692 | al2.allocate_l2(3 * _1m, _1m, &allocated4, &a4); | |
11fdf7f2 | 693 | ASSERT_EQ(a4.size(), 2u); |
a8e16298 TL |
694 | ASSERT_EQ(allocated4, 3 * _1m); |
695 | ASSERT_EQ(a4[0].offset, _1m); | |
696 | ASSERT_EQ(a4[0].length, _1m); | |
697 | ASSERT_EQ(a4[1].offset, capacity / 2); | |
698 | ASSERT_EQ(a4[1].length, 2 * _1m); | |
699 | bins_overall.clear(); | |
700 | al2.collect_stats(bins_overall); | |
701 | ASSERT_EQ(bins_overall.size(), 3u); | |
702 | ASSERT_EQ(bins_overall[0], 1u); | |
703 | ASSERT_EQ(bins_overall[cbits((_1m - 0x3000) / 0x1000) - 1], 1u); | |
704 | ASSERT_EQ(bins_overall[cbits((num_chunks - 512) / 2) - 1], 1u); | |
705 | } | |
706 | { | |
707 | // release allocated 1M in the second meg chunk except | |
708 | // the first 4K chunk | |
709 | interval_vector_t r; | |
710 | r.emplace_back(_1m + 0x1000, _1m); | |
711 | al2.free_l2(r); | |
712 | bins_overall.clear(); | |
713 | al2.collect_stats(bins_overall); | |
714 | ASSERT_EQ(bins_overall.size(), 3u); | |
715 | ASSERT_EQ(bins_overall[cbits(_1m / 0x1000) - 1], 1u); | |
716 | ASSERT_EQ(bins_overall[cbits((_1m - 0x3000) / 0x1000) - 1], 1u); | |
717 | ASSERT_EQ(bins_overall[cbits((num_chunks - 512) / 2) - 1], 1u); | |
718 | } | |
719 | { | |
720 | // release 2M @(capacity / 2) | |
721 | interval_vector_t r; | |
722 | r.emplace_back(capacity / 2, 2 * _1m); | |
723 | al2.free_l2(r); | |
724 | bins_overall.clear(); | |
725 | al2.collect_stats(bins_overall); | |
726 | ASSERT_EQ(bins_overall.size(), 3u); | |
727 | ASSERT_EQ(bins_overall[cbits(_1m / 0x1000) - 1], 1u); | |
728 | ASSERT_EQ(bins_overall[cbits((_1m - 0x3000) / 0x1000) - 1], 1u); | |
729 | ASSERT_EQ(bins_overall[cbits((num_chunks) / 2) - 1], 1u); | |
730 | } | |
731 | { | |
732 | // allocate 4x512K - should go to the second halves of | |
733 | // the first and second 1M chunks and @(capacity / 2) | |
734 | uint64_t allocated4 = 0; | |
735 | interval_vector_t a4; | |
736 | al2.allocate_l2(2 * _1m, _1m / 2, &allocated4, &a4); | |
11fdf7f2 | 737 | ASSERT_EQ(a4.size(), 3u); |
a8e16298 TL |
738 | ASSERT_EQ(allocated4, 2 * _1m); |
739 | ASSERT_EQ(a4[0].offset, _1m / 2); | |
740 | ASSERT_EQ(a4[0].length, _1m / 2); | |
741 | ASSERT_EQ(a4[1].offset, _1m + _1m / 2); | |
742 | ASSERT_EQ(a4[1].length, _1m / 2); | |
743 | ASSERT_EQ(a4[2].offset, capacity / 2); | |
744 | ASSERT_EQ(a4[2].length, _1m); | |
745 | ||
746 | bins_overall.clear(); | |
747 | al2.collect_stats(bins_overall); | |
748 | ASSERT_EQ(bins_overall.size(), 3u); | |
749 | ASSERT_EQ(bins_overall[0], 1u); | |
750 | // below we have 512K - 4K & 512K - 12K chunks which both fit into | |
751 | // the same bin = 6 | |
752 | ASSERT_EQ(bins_overall[6], 2u); | |
753 | ASSERT_EQ(bins_overall[cbits((num_chunks - 256) / 2) - 1], 1u); | |
754 | ||
755 | } | |
756 | { | |
757 | // cleanup first 2M except except the last 4K chunk | |
758 | interval_vector_t r; | |
759 | r.emplace_back(0, 2 * _1m - 0x1000); | |
760 | al2.free_l2(r); | |
761 | bins_overall.clear(); | |
762 | al2.collect_stats(bins_overall); | |
763 | ||
764 | ASSERT_EQ(bins_overall.size(), 3u); | |
765 | ASSERT_EQ(bins_overall[0], 1u); | |
766 | ASSERT_EQ(bins_overall[cbits((_2m - 0x1000) / 0x1000) - 1], 1u); | |
767 | ASSERT_EQ(bins_overall[cbits((num_chunks - 256) / 2) - 1], 1u); | |
768 | } | |
769 | { | |
770 | // release 2M @(capacity / 2) | |
771 | interval_vector_t r; | |
772 | r.emplace_back(capacity / 2, 2 * _1m); | |
773 | al2.free_l2(r); | |
774 | bins_overall.clear(); | |
775 | al2.collect_stats(bins_overall); | |
776 | ||
777 | ASSERT_EQ(bins_overall.size(), 3u); | |
778 | ASSERT_EQ(bins_overall[0], 1u); | |
779 | ASSERT_EQ(bins_overall[cbits((_2m - 0x1000) / 0x1000) - 1], 1u); | |
780 | ASSERT_EQ(bins_overall[cbits(num_chunks / 2) - 1], 1u); | |
781 | } | |
782 | { | |
783 | // allocate 132M using 4M granularity should go to (capacity / 2) | |
784 | uint64_t allocated4 = 0; | |
785 | interval_vector_t a4; | |
786 | al2.allocate_l2(132 * _1m, 4 * _1m , &allocated4, &a4); | |
11fdf7f2 | 787 | ASSERT_EQ(a4.size(), 1u); |
a8e16298 TL |
788 | ASSERT_EQ(a4[0].offset, capacity / 2); |
789 | ASSERT_EQ(a4[0].length, 132 * _1m); | |
790 | ||
791 | bins_overall.clear(); | |
792 | al2.collect_stats(bins_overall); | |
793 | ASSERT_EQ(bins_overall.size(), 3u); | |
794 | } | |
795 | { | |
796 | // cleanup left 4K chunk in the first 2M | |
797 | interval_vector_t r; | |
798 | r.emplace_back(2 * _1m - 0x1000, 0x1000); | |
799 | al2.free_l2(r); | |
800 | bins_overall.clear(); | |
801 | al2.collect_stats(bins_overall); | |
802 | ||
803 | ASSERT_EQ(bins_overall.size(), 2u); | |
804 | } | |
805 | { | |
806 | // release 132M @(capacity / 2) | |
807 | interval_vector_t r; | |
808 | r.emplace_back(capacity / 2, 132 * _1m); | |
809 | al2.free_l2(r); | |
810 | } | |
811 | { | |
812 | // allocate 132M using 2M granularity should go to the first chunk and to | |
813 | // (capacity / 2) | |
814 | uint64_t allocated4 = 0; | |
815 | interval_vector_t a4; | |
816 | al2.allocate_l2(132 * _1m, 2 * _1m , &allocated4, &a4); | |
11fdf7f2 TL |
817 | ASSERT_EQ(a4.size(), 2u); |
818 | ASSERT_EQ(a4[0].offset, 0u); | |
a8e16298 TL |
819 | ASSERT_EQ(a4[0].length, 2 * _1m); |
820 | ASSERT_EQ(a4[1].offset, capacity / 2); | |
821 | ASSERT_EQ(a4[1].length, 130 * _1m); | |
822 | } | |
823 | { | |
824 | // release 130M @(capacity / 2) | |
825 | interval_vector_t r; | |
826 | r.emplace_back(capacity / 2, 132 * _1m); | |
827 | al2.free_l2(r); | |
828 | } | |
829 | { | |
830 | // release 4K~16K | |
831 | // release 28K~32K | |
832 | // release 68K~24K | |
833 | interval_vector_t r; | |
834 | r.emplace_back(0x1000, 0x4000); | |
835 | r.emplace_back(0x7000, 0x8000); | |
836 | r.emplace_back(0x11000, 0x6000); | |
837 | al2.free_l2(r); | |
838 | } | |
839 | { | |
840 | // allocate 32K using 16K granularity - should bypass the first | |
841 | // unaligned extent, use the second free extent partially given | |
842 | // the 16K alignment and then fallback to capacity / 2 | |
843 | uint64_t allocated4 = 0; | |
844 | interval_vector_t a4; | |
845 | al2.allocate_l2(0x8000, 0x4000, &allocated4, &a4); | |
11fdf7f2 TL |
846 | ASSERT_EQ(a4.size(), 2u); |
847 | ASSERT_EQ(a4[0].offset, 0x8000u); | |
848 | ASSERT_EQ(a4[0].length, 0x4000u); | |
a8e16298 | 849 | ASSERT_EQ(a4[1].offset, capacity / 2); |
11fdf7f2 | 850 | ASSERT_EQ(a4[1].length, 0x4000u); |
a8e16298 TL |
851 | } |
852 | ||
853 | } | |
854 | std::cout << "Done L2 cont aligned" << std::endl; | |
855 | } | |
856 | ||
857 | TEST(TestAllocatorLevel01, test_4G_alloc_bug) | |
858 | { | |
859 | { | |
860 | TestAllocatorLevel02 al2; | |
861 | uint64_t capacity = 0x8000 * _1m; // = 32GB | |
862 | al2.init(capacity, 0x10000); | |
863 | std::cout << "Init L2 cont aligned" << std::endl; | |
864 | ||
865 | uint64_t allocated4 = 0; | |
866 | interval_vector_t a4; | |
867 | al2.allocate_l2(_1m, _1m, &allocated4, &a4); | |
868 | ASSERT_EQ(a4.size(), 1u); // the bug caused no allocations here | |
869 | ASSERT_EQ(allocated4, _1m); | |
870 | ASSERT_EQ(a4[0].offset, 0u); | |
871 | ASSERT_EQ(a4[0].length, _1m); | |
872 | } | |
873 | } | |
874 | ||
875 | TEST(TestAllocatorLevel01, test_4G_alloc_bug2) | |
876 | { | |
877 | { | |
878 | TestAllocatorLevel02 al2; | |
879 | uint64_t capacity = 0x8000 * _1m; // = 32GB | |
880 | al2.init(capacity, 0x10000); | |
881 | ||
882 | for (uint64_t i = 0; i < capacity; i += _1m) { | |
883 | uint64_t allocated4 = 0; | |
884 | interval_vector_t a4; | |
885 | al2.allocate_l2(_1m, _1m, &allocated4, &a4); | |
886 | ASSERT_EQ(a4.size(), 1u); | |
887 | ASSERT_EQ(allocated4, _1m); | |
888 | ASSERT_EQ(a4[0].offset, i); | |
889 | ASSERT_EQ(a4[0].length, _1m); | |
890 | } | |
891 | ASSERT_EQ(0u , al2.debug_get_free()); | |
892 | ||
893 | interval_vector_t r; | |
894 | r.emplace_back(0x5fec30000, 0x13d0000); | |
895 | r.emplace_back(0x628000000, 0x80000000); | |
896 | r.emplace_back(0x6a8000000, 0x80000000); | |
897 | r.emplace_back(0x728100000, 0x70000); | |
898 | al2.free_l2(r); | |
899 | ||
900 | std::map<size_t, size_t> bins_overall; | |
901 | al2.collect_stats(bins_overall); | |
902 | ||
903 | uint64_t allocated4 = 0; | |
904 | interval_vector_t a4; | |
905 | al2.allocate_l2(0x3e000000, _1m, &allocated4, &a4); | |
906 | ASSERT_EQ(a4.size(), 2u); | |
907 | ASSERT_EQ(allocated4, 0x3e000000u); | |
908 | ASSERT_EQ(a4[0].offset, 0x5fed00000u); | |
909 | ASSERT_EQ(a4[0].length, 0x1300000u); | |
910 | ASSERT_EQ(a4[1].offset, 0x628000000u); | |
911 | ASSERT_EQ(a4[1].length, 0x3cd00000u); | |
912 | } | |
913 | } | |
914 | ||
915 | TEST(TestAllocatorLevel01, test_4G_alloc_bug3) | |
916 | { | |
917 | { | |
918 | TestAllocatorLevel02 al2; | |
919 | uint64_t capacity = 0x8000 * _1m; // = 32GB | |
920 | al2.init(capacity, 0x10000); | |
921 | std::cout << "Init L2 cont aligned" << std::endl; | |
922 | ||
923 | uint64_t allocated4 = 0; | |
924 | interval_vector_t a4; | |
925 | al2.allocate_l2(4096ull * _1m, _1m, &allocated4, &a4); | |
926 | ASSERT_EQ(a4.size(), 2u); // allocator has to split into 2 allocations | |
927 | ASSERT_EQ(allocated4, 4096ull * _1m); | |
928 | ASSERT_EQ(a4[0].offset, 0u); | |
929 | ASSERT_EQ(a4[0].length, 2048ull * _1m); | |
930 | ASSERT_EQ(a4[1].offset, 2048ull * _1m); | |
931 | ASSERT_EQ(a4[1].length, 2048ull * _1m); | |
932 | } | |
933 | } |