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