2 * Hierarchical bitmap unit-tests.
4 * Copyright (C) 2012 Red Hat Inc.
6 * Author: Paolo Bonzini <pbonzini@redhat.com>
8 * This work is licensed under the terms of the GNU GPL, version 2 or later.
9 * See the COPYING file in the top-level directory.
14 #include "qemu/hbitmap.h"
16 #define LOG_BITS_PER_LONG (BITS_PER_LONG == 32 ? 5 : 6)
18 #define L1 BITS_PER_LONG
19 #define L2 (BITS_PER_LONG * L1)
20 #define L3 (BITS_PER_LONG * L2)
22 typedef struct TestHBitmapData
{
30 /* Check that the HBitmap and the shadow bitmap contain the same data,
31 * ignoring the same "first" bits.
33 static void hbitmap_test_check(TestHBitmapData
*data
,
42 hbitmap_iter_init(&hbi
, data
->hb
, first
);
46 next
= hbitmap_iter_next(&hbi
);
52 pos
= i
>> LOG_BITS_PER_LONG
;
53 bit
= i
& (BITS_PER_LONG
- 1);
55 g_assert_cmpint(data
->bits
[pos
] & (1UL << bit
), ==, 0);
58 if (next
== data
->size
) {
62 pos
= i
>> LOG_BITS_PER_LONG
;
63 bit
= i
& (BITS_PER_LONG
- 1);
66 g_assert_cmpint(data
->bits
[pos
] & (1UL << bit
), !=, 0);
70 g_assert_cmpint(count
<< data
->granularity
, ==, hbitmap_count(data
->hb
));
74 /* This is provided instead of a test setup function so that the sizes
75 are kept in the test functions (and not in main()) */
76 static void hbitmap_test_init(TestHBitmapData
*data
,
77 uint64_t size
, int granularity
)
80 data
->hb
= hbitmap_alloc(size
, granularity
);
82 n
= (size
+ BITS_PER_LONG
- 1) / BITS_PER_LONG
;
86 data
->bits
= g_new0(unsigned long, n
);
88 data
->granularity
= granularity
;
90 hbitmap_test_check(data
, 0);
94 static void hbitmap_test_teardown(TestHBitmapData
*data
,
98 hbitmap_free(data
->hb
);
107 /* Set a range in the HBitmap and in the shadow "simple" bitmap.
108 * The two bitmaps are then tested against each other.
110 static void hbitmap_test_set(TestHBitmapData
*data
,
111 uint64_t first
, uint64_t count
)
113 hbitmap_set(data
->hb
, first
, count
);
114 while (count
-- != 0) {
115 size_t pos
= first
>> LOG_BITS_PER_LONG
;
116 int bit
= first
& (BITS_PER_LONG
- 1);
119 data
->bits
[pos
] |= 1UL << bit
;
122 if (data
->granularity
== 0) {
123 hbitmap_test_check(data
, 0);
127 /* Reset a range in the HBitmap and in the shadow "simple" bitmap.
129 static void hbitmap_test_reset(TestHBitmapData
*data
,
130 uint64_t first
, uint64_t count
)
132 hbitmap_reset(data
->hb
, first
, count
);
133 while (count
-- != 0) {
134 size_t pos
= first
>> LOG_BITS_PER_LONG
;
135 int bit
= first
& (BITS_PER_LONG
- 1);
138 data
->bits
[pos
] &= ~(1UL << bit
);
141 if (data
->granularity
== 0) {
142 hbitmap_test_check(data
, 0);
146 static void hbitmap_test_check_get(TestHBitmapData
*data
)
151 for (i
= 0; i
< data
->size
; i
++) {
152 size_t pos
= i
>> LOG_BITS_PER_LONG
;
153 int bit
= i
& (BITS_PER_LONG
- 1);
154 unsigned long val
= data
->bits
[pos
] & (1UL << bit
);
155 count
+= hbitmap_get(data
->hb
, i
);
156 g_assert_cmpint(hbitmap_get(data
->hb
, i
), ==, val
!= 0);
158 g_assert_cmpint(count
, ==, hbitmap_count(data
->hb
));
161 static void test_hbitmap_zero(TestHBitmapData
*data
,
164 hbitmap_test_init(data
, 0, 0);
167 static void test_hbitmap_unaligned(TestHBitmapData
*data
,
170 hbitmap_test_init(data
, L3
+ 23, 0);
171 hbitmap_test_set(data
, 0, 1);
172 hbitmap_test_set(data
, L3
+ 22, 1);
175 static void test_hbitmap_iter_empty(TestHBitmapData
*data
,
178 hbitmap_test_init(data
, L1
, 0);
181 static void test_hbitmap_iter_partial(TestHBitmapData
*data
,
184 hbitmap_test_init(data
, L3
, 0);
185 hbitmap_test_set(data
, 0, L3
);
186 hbitmap_test_check(data
, 1);
187 hbitmap_test_check(data
, L1
- 1);
188 hbitmap_test_check(data
, L1
);
189 hbitmap_test_check(data
, L1
* 2 - 1);
190 hbitmap_test_check(data
, L2
- 1);
191 hbitmap_test_check(data
, L2
);
192 hbitmap_test_check(data
, L2
+ 1);
193 hbitmap_test_check(data
, L2
+ L1
);
194 hbitmap_test_check(data
, L2
+ L1
* 2 - 1);
195 hbitmap_test_check(data
, L2
* 2 - 1);
196 hbitmap_test_check(data
, L2
* 2);
197 hbitmap_test_check(data
, L2
* 2 + 1);
198 hbitmap_test_check(data
, L2
* 2 + L1
);
199 hbitmap_test_check(data
, L2
* 2 + L1
* 2 - 1);
200 hbitmap_test_check(data
, L3
/ 2);
203 static void test_hbitmap_set_all(TestHBitmapData
*data
,
206 hbitmap_test_init(data
, L3
, 0);
207 hbitmap_test_set(data
, 0, L3
);
210 static void test_hbitmap_get_all(TestHBitmapData
*data
,
213 hbitmap_test_init(data
, L3
, 0);
214 hbitmap_test_set(data
, 0, L3
);
215 hbitmap_test_check_get(data
);
218 static void test_hbitmap_get_some(TestHBitmapData
*data
,
221 hbitmap_test_init(data
, 2 * L2
, 0);
222 hbitmap_test_set(data
, 10, 1);
223 hbitmap_test_check_get(data
);
224 hbitmap_test_set(data
, L1
- 1, 1);
225 hbitmap_test_check_get(data
);
226 hbitmap_test_set(data
, L1
, 1);
227 hbitmap_test_check_get(data
);
228 hbitmap_test_set(data
, L2
- 1, 1);
229 hbitmap_test_check_get(data
);
230 hbitmap_test_set(data
, L2
, 1);
231 hbitmap_test_check_get(data
);
234 static void test_hbitmap_set_one(TestHBitmapData
*data
,
237 hbitmap_test_init(data
, 2 * L2
, 0);
238 hbitmap_test_set(data
, 10, 1);
239 hbitmap_test_set(data
, L1
- 1, 1);
240 hbitmap_test_set(data
, L1
, 1);
241 hbitmap_test_set(data
, L2
- 1, 1);
242 hbitmap_test_set(data
, L2
, 1);
245 static void test_hbitmap_set_two_elem(TestHBitmapData
*data
,
248 hbitmap_test_init(data
, 2 * L2
, 0);
249 hbitmap_test_set(data
, L1
- 1, 2);
250 hbitmap_test_set(data
, L1
* 2 - 1, 4);
251 hbitmap_test_set(data
, L1
* 4, L1
+ 1);
252 hbitmap_test_set(data
, L1
* 8 - 1, L1
+ 1);
253 hbitmap_test_set(data
, L2
- 1, 2);
254 hbitmap_test_set(data
, L2
+ L1
- 1, 8);
255 hbitmap_test_set(data
, L2
+ L1
* 4, L1
+ 1);
256 hbitmap_test_set(data
, L2
+ L1
* 8 - 1, L1
+ 1);
259 static void test_hbitmap_set(TestHBitmapData
*data
,
262 hbitmap_test_init(data
, L3
* 2, 0);
263 hbitmap_test_set(data
, L1
- 1, L1
+ 2);
264 hbitmap_test_set(data
, L1
* 3 - 1, L1
+ 2);
265 hbitmap_test_set(data
, L1
* 5, L1
* 2 + 1);
266 hbitmap_test_set(data
, L1
* 8 - 1, L1
* 2 + 1);
267 hbitmap_test_set(data
, L2
- 1, L1
+ 2);
268 hbitmap_test_set(data
, L2
+ L1
* 2 - 1, L1
+ 2);
269 hbitmap_test_set(data
, L2
+ L1
* 4, L1
* 2 + 1);
270 hbitmap_test_set(data
, L2
+ L1
* 7 - 1, L1
* 2 + 1);
271 hbitmap_test_set(data
, L2
* 2 - 1, L3
* 2 - L2
* 2);
274 static void test_hbitmap_set_twice(TestHBitmapData
*data
,
277 hbitmap_test_init(data
, L1
* 3, 0);
278 hbitmap_test_set(data
, 0, L1
* 3);
279 hbitmap_test_set(data
, L1
, 1);
282 static void test_hbitmap_set_overlap(TestHBitmapData
*data
,
285 hbitmap_test_init(data
, L3
* 2, 0);
286 hbitmap_test_set(data
, L1
- 1, L1
+ 2);
287 hbitmap_test_set(data
, L1
* 2 - 1, L1
* 2 + 2);
288 hbitmap_test_set(data
, 0, L1
* 3);
289 hbitmap_test_set(data
, L1
* 8 - 1, L2
);
290 hbitmap_test_set(data
, L2
, L1
);
291 hbitmap_test_set(data
, L2
- L1
- 1, L1
* 8 + 2);
292 hbitmap_test_set(data
, L2
, L3
- L2
+ 1);
293 hbitmap_test_set(data
, L3
- L1
, L1
* 3);
294 hbitmap_test_set(data
, L3
- 1, 3);
295 hbitmap_test_set(data
, L3
- 1, L2
);
298 static void test_hbitmap_reset_empty(TestHBitmapData
*data
,
301 hbitmap_test_init(data
, L3
, 0);
302 hbitmap_test_reset(data
, 0, L3
);
305 static void test_hbitmap_reset(TestHBitmapData
*data
,
308 hbitmap_test_init(data
, L3
* 2, 0);
309 hbitmap_test_set(data
, L1
- 1, L1
+ 2);
310 hbitmap_test_reset(data
, L1
* 2 - 1, L1
* 2 + 2);
311 hbitmap_test_set(data
, 0, L1
* 3);
312 hbitmap_test_reset(data
, L1
* 8 - 1, L2
);
313 hbitmap_test_set(data
, L2
, L1
);
314 hbitmap_test_reset(data
, L2
- L1
- 1, L1
* 8 + 2);
315 hbitmap_test_set(data
, L2
, L3
- L2
+ 1);
316 hbitmap_test_reset(data
, L3
- L1
, L1
* 3);
317 hbitmap_test_set(data
, L3
- 1, 3);
318 hbitmap_test_reset(data
, L3
- 1, L2
);
319 hbitmap_test_set(data
, 0, L3
* 2);
320 hbitmap_test_reset(data
, 0, L1
);
321 hbitmap_test_reset(data
, 0, L2
);
322 hbitmap_test_reset(data
, L3
, L3
);
323 hbitmap_test_set(data
, L3
/ 2, L3
);
326 static void test_hbitmap_granularity(TestHBitmapData
*data
,
329 /* Note that hbitmap_test_check has to be invoked manually in this test. */
330 hbitmap_test_init(data
, L1
, 1);
331 hbitmap_test_set(data
, 0, 1);
332 g_assert_cmpint(hbitmap_count(data
->hb
), ==, 2);
333 hbitmap_test_check(data
, 0);
334 hbitmap_test_set(data
, 2, 1);
335 g_assert_cmpint(hbitmap_count(data
->hb
), ==, 4);
336 hbitmap_test_check(data
, 0);
337 hbitmap_test_set(data
, 0, 3);
338 g_assert_cmpint(hbitmap_count(data
->hb
), ==, 4);
339 hbitmap_test_reset(data
, 0, 1);
340 g_assert_cmpint(hbitmap_count(data
->hb
), ==, 2);
343 static void test_hbitmap_iter_granularity(TestHBitmapData
*data
,
348 /* Note that hbitmap_test_check has to be invoked manually in this test. */
349 hbitmap_test_init(data
, 131072 << 7, 7);
350 hbitmap_iter_init(&hbi
, data
->hb
, 0);
351 g_assert_cmpint(hbitmap_iter_next(&hbi
), <, 0);
353 hbitmap_test_set(data
, ((L2
+ L1
+ 1) << 7) + 8, 8);
354 hbitmap_iter_init(&hbi
, data
->hb
, 0);
355 g_assert_cmpint(hbitmap_iter_next(&hbi
), ==, (L2
+ L1
+ 1) << 7);
356 g_assert_cmpint(hbitmap_iter_next(&hbi
), <, 0);
358 hbitmap_iter_init(&hbi
, data
->hb
, (L2
+ L1
+ 2) << 7);
359 g_assert_cmpint(hbitmap_iter_next(&hbi
), <, 0);
361 hbitmap_test_set(data
, (131072 << 7) - 8, 8);
362 hbitmap_iter_init(&hbi
, data
->hb
, 0);
363 g_assert_cmpint(hbitmap_iter_next(&hbi
), ==, (L2
+ L1
+ 1) << 7);
364 g_assert_cmpint(hbitmap_iter_next(&hbi
), ==, 131071 << 7);
365 g_assert_cmpint(hbitmap_iter_next(&hbi
), <, 0);
367 hbitmap_iter_init(&hbi
, data
->hb
, (L2
+ L1
+ 2) << 7);
368 g_assert_cmpint(hbitmap_iter_next(&hbi
), ==, 131071 << 7);
369 g_assert_cmpint(hbitmap_iter_next(&hbi
), <, 0);
372 static void hbitmap_test_add(const char *testpath
,
373 void (*test_func
)(TestHBitmapData
*data
, const void *user_data
))
375 g_test_add(testpath
, TestHBitmapData
, NULL
, NULL
, test_func
,
376 hbitmap_test_teardown
);
379 int main(int argc
, char **argv
)
381 g_test_init(&argc
, &argv
, NULL
);
382 hbitmap_test_add("/hbitmap/size/0", test_hbitmap_zero
);
383 hbitmap_test_add("/hbitmap/size/unaligned", test_hbitmap_unaligned
);
384 hbitmap_test_add("/hbitmap/iter/empty", test_hbitmap_iter_empty
);
385 hbitmap_test_add("/hbitmap/iter/partial", test_hbitmap_iter_partial
);
386 hbitmap_test_add("/hbitmap/iter/granularity", test_hbitmap_iter_granularity
);
387 hbitmap_test_add("/hbitmap/get/all", test_hbitmap_get_all
);
388 hbitmap_test_add("/hbitmap/get/some", test_hbitmap_get_some
);
389 hbitmap_test_add("/hbitmap/set/all", test_hbitmap_set_all
);
390 hbitmap_test_add("/hbitmap/set/one", test_hbitmap_set_one
);
391 hbitmap_test_add("/hbitmap/set/two-elem", test_hbitmap_set_two_elem
);
392 hbitmap_test_add("/hbitmap/set/general", test_hbitmap_set
);
393 hbitmap_test_add("/hbitmap/set/twice", test_hbitmap_set_twice
);
394 hbitmap_test_add("/hbitmap/set/overlap", test_hbitmap_set_overlap
);
395 hbitmap_test_add("/hbitmap/reset/empty", test_hbitmap_reset_empty
);
396 hbitmap_test_add("/hbitmap/reset/general", test_hbitmap_reset
);
397 hbitmap_test_add("/hbitmap/granularity", test_hbitmap_granularity
);