Peter Xu | ad37f24 | 2019-06-03 14:50:49 +0800 | [diff] [blame] | 1 | /* |
| 2 | * SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | * |
| 4 | * Bitmap.c unit-tests. |
| 5 | * |
| 6 | * Copyright (C) 2019, Red Hat, Inc. |
| 7 | * |
| 8 | * Author: Peter Xu <peterx@redhat.com> |
| 9 | */ |
| 10 | |
| 11 | #include <stdlib.h> |
| 12 | #include "qemu/osdep.h" |
| 13 | #include "qemu/bitmap.h" |
| 14 | |
| 15 | #define BMAP_SIZE 1024 |
| 16 | |
| 17 | static void check_bitmap_copy_with_offset(void) |
| 18 | { |
| 19 | unsigned long *bmap1, *bmap2, *bmap3, total; |
| 20 | |
| 21 | bmap1 = bitmap_new(BMAP_SIZE); |
| 22 | bmap2 = bitmap_new(BMAP_SIZE); |
| 23 | bmap3 = bitmap_new(BMAP_SIZE); |
| 24 | |
Paolo Bonzini | 0f55560 | 2019-12-12 02:17:58 +0100 | [diff] [blame] | 25 | bmap1[0] = g_test_rand_int(); |
| 26 | bmap1[1] = g_test_rand_int(); |
| 27 | bmap1[2] = g_test_rand_int(); |
| 28 | bmap1[3] = g_test_rand_int(); |
Peter Xu | ad37f24 | 2019-06-03 14:50:49 +0800 | [diff] [blame] | 29 | total = BITS_PER_LONG * 4; |
| 30 | |
| 31 | /* Shift 115 bits into bmap2 */ |
| 32 | bitmap_copy_with_dst_offset(bmap2, bmap1, 115, total); |
| 33 | /* Shift another 85 bits into bmap3 */ |
| 34 | bitmap_copy_with_dst_offset(bmap3, bmap2, 85, total + 115); |
| 35 | /* Shift back 200 bits back */ |
| 36 | bitmap_copy_with_src_offset(bmap2, bmap3, 200, total); |
| 37 | |
| 38 | g_assert_cmpmem(bmap1, total / BITS_PER_LONG, |
| 39 | bmap2, total / BITS_PER_LONG); |
| 40 | |
| 41 | bitmap_clear(bmap1, 0, BMAP_SIZE); |
| 42 | /* Set bits in bmap1 are 100-245 */ |
| 43 | bitmap_set(bmap1, 100, 145); |
| 44 | |
| 45 | /* Set bits in bmap2 are 60-205 */ |
| 46 | bitmap_copy_with_src_offset(bmap2, bmap1, 40, 250); |
| 47 | g_assert_cmpint(find_first_bit(bmap2, 60), ==, 60); |
| 48 | g_assert_cmpint(find_next_zero_bit(bmap2, 205, 60), ==, 205); |
| 49 | g_assert(test_bit(205, bmap2) == 0); |
| 50 | |
| 51 | /* Set bits in bmap3 are 135-280 */ |
| 52 | bitmap_copy_with_dst_offset(bmap3, bmap1, 35, 250); |
| 53 | g_assert_cmpint(find_first_bit(bmap3, 135), ==, 135); |
| 54 | g_assert_cmpint(find_next_zero_bit(bmap3, 280, 135), ==, 280); |
| 55 | g_assert(test_bit(280, bmap3) == 0); |
| 56 | |
| 57 | g_free(bmap1); |
| 58 | g_free(bmap2); |
| 59 | g_free(bmap3); |
| 60 | } |
| 61 | |
Wei Yang | 2f950b1 | 2019-07-18 09:04:56 +0800 | [diff] [blame] | 62 | typedef void (*bmap_set_func)(unsigned long *map, long i, long len); |
| 63 | static void bitmap_set_case(bmap_set_func set_func) |
| 64 | { |
| 65 | unsigned long *bmap; |
| 66 | int offset; |
| 67 | |
| 68 | bmap = bitmap_new(BMAP_SIZE); |
| 69 | |
Wei Yang | a060297 | 2019-08-14 08:27:23 +0800 | [diff] [blame] | 70 | /* Set one bit at offset in second word */ |
| 71 | for (offset = 0; offset <= BITS_PER_LONG; offset++) { |
| 72 | bitmap_clear(bmap, 0, BMAP_SIZE); |
| 73 | set_func(bmap, BITS_PER_LONG + offset, 1); |
| 74 | g_assert_cmpint(find_first_bit(bmap, 2 * BITS_PER_LONG), |
| 75 | ==, BITS_PER_LONG + offset); |
| 76 | g_assert_cmpint(find_next_zero_bit(bmap, |
| 77 | 3 * BITS_PER_LONG, |
| 78 | BITS_PER_LONG + offset), |
| 79 | ==, BITS_PER_LONG + offset + 1); |
| 80 | } |
| 81 | |
Wei Yang | 2f950b1 | 2019-07-18 09:04:56 +0800 | [diff] [blame] | 82 | /* Both Aligned, set bits [BITS_PER_LONG, 3*BITS_PER_LONG] */ |
| 83 | set_func(bmap, BITS_PER_LONG, 2 * BITS_PER_LONG); |
| 84 | g_assert_cmpuint(bmap[1], ==, -1ul); |
| 85 | g_assert_cmpuint(bmap[2], ==, -1ul); |
| 86 | g_assert_cmpint(find_first_bit(bmap, BITS_PER_LONG), ==, BITS_PER_LONG); |
| 87 | g_assert_cmpint(find_next_zero_bit(bmap, 3 * BITS_PER_LONG, BITS_PER_LONG), |
| 88 | ==, 3 * BITS_PER_LONG); |
| 89 | |
| 90 | for (offset = 0; offset <= BITS_PER_LONG; offset++) { |
| 91 | bitmap_clear(bmap, 0, BMAP_SIZE); |
| 92 | /* End Aligned, set bits [BITS_PER_LONG - offset, 3*BITS_PER_LONG] */ |
| 93 | set_func(bmap, BITS_PER_LONG - offset, 2 * BITS_PER_LONG + offset); |
| 94 | g_assert_cmpuint(bmap[1], ==, -1ul); |
| 95 | g_assert_cmpuint(bmap[2], ==, -1ul); |
| 96 | g_assert_cmpint(find_first_bit(bmap, BITS_PER_LONG), |
| 97 | ==, BITS_PER_LONG - offset); |
| 98 | g_assert_cmpint(find_next_zero_bit(bmap, |
| 99 | 3 * BITS_PER_LONG, |
| 100 | BITS_PER_LONG - offset), |
| 101 | ==, 3 * BITS_PER_LONG); |
| 102 | } |
| 103 | |
| 104 | for (offset = 0; offset <= BITS_PER_LONG; offset++) { |
| 105 | bitmap_clear(bmap, 0, BMAP_SIZE); |
| 106 | /* Start Aligned, set bits [BITS_PER_LONG, 3*BITS_PER_LONG + offset] */ |
| 107 | set_func(bmap, BITS_PER_LONG, 2 * BITS_PER_LONG + offset); |
| 108 | g_assert_cmpuint(bmap[1], ==, -1ul); |
| 109 | g_assert_cmpuint(bmap[2], ==, -1ul); |
| 110 | g_assert_cmpint(find_first_bit(bmap, BITS_PER_LONG), |
| 111 | ==, BITS_PER_LONG); |
| 112 | g_assert_cmpint(find_next_zero_bit(bmap, |
| 113 | 3 * BITS_PER_LONG + offset, |
| 114 | BITS_PER_LONG), |
| 115 | ==, 3 * BITS_PER_LONG + offset); |
| 116 | } |
| 117 | |
| 118 | g_free(bmap); |
| 119 | } |
| 120 | |
| 121 | static void check_bitmap_set(void) |
| 122 | { |
| 123 | bitmap_set_case(bitmap_set); |
| 124 | bitmap_set_case(bitmap_set_atomic); |
| 125 | } |
| 126 | |
Peter Xu | ad37f24 | 2019-06-03 14:50:49 +0800 | [diff] [blame] | 127 | int main(int argc, char **argv) |
| 128 | { |
| 129 | g_test_init(&argc, &argv, NULL); |
| 130 | |
| 131 | g_test_add_func("/bitmap/bitmap_copy_with_offset", |
| 132 | check_bitmap_copy_with_offset); |
Wei Yang | 2f950b1 | 2019-07-18 09:04:56 +0800 | [diff] [blame] | 133 | g_test_add_func("/bitmap/bitmap_set", |
| 134 | check_bitmap_set); |
Peter Xu | ad37f24 | 2019-06-03 14:50:49 +0800 | [diff] [blame] | 135 | |
| 136 | g_test_run(); |
| 137 | |
| 138 | return 0; |
| 139 | } |