1f1b079b4SArtur Paszkiewicz /* SPDX-License-Identifier: BSD-3-Clause
2a6dbe372Spaul luse * Copyright (C) 2022 Intel Corporation.
3f1b079b4SArtur Paszkiewicz * All rights reserved.
4f1b079b4SArtur Paszkiewicz */
5f1b079b4SArtur Paszkiewicz
6f1b079b4SArtur Paszkiewicz #include "spdk/stdinc.h"
7f1b079b4SArtur Paszkiewicz
8ae431e31SKonrad Sztyber #include "spdk_internal/cunit.h"
9f1b079b4SArtur Paszkiewicz
10f1b079b4SArtur Paszkiewicz #include "ftl/utils/ftl_bitmap.c"
11f1b079b4SArtur Paszkiewicz
12f1b079b4SArtur Paszkiewicz #define BITMAP_SIZE 64
13f1b079b4SArtur Paszkiewicz #define BITMAP_CAPACITY (BITMAP_SIZE * 8)
14f1b079b4SArtur Paszkiewicz
15f1b079b4SArtur Paszkiewicz #define TEST_BIT(bi, bbi) \
16f1b079b4SArtur Paszkiewicz { .byte_idx = (bi), .byte_bit_idx = (bbi), .bit_idx = (((bi) * 8) + (bbi)) }
17f1b079b4SArtur Paszkiewicz
18f1b079b4SArtur Paszkiewicz static struct {
19f1b079b4SArtur Paszkiewicz size_t byte_idx;
20f1b079b4SArtur Paszkiewicz uint8_t byte_bit_idx;
21f1b079b4SArtur Paszkiewicz uint64_t bit_idx;
22f1b079b4SArtur Paszkiewicz } g_test_bits[] = {
23f1b079b4SArtur Paszkiewicz TEST_BIT(0, 0),
24f1b079b4SArtur Paszkiewicz TEST_BIT(0, 1),
25f1b079b4SArtur Paszkiewicz TEST_BIT(0, 2),
26f1b079b4SArtur Paszkiewicz TEST_BIT(1, 3),
27f1b079b4SArtur Paszkiewicz TEST_BIT(2, 4),
28f1b079b4SArtur Paszkiewicz TEST_BIT(3, 5),
29f1b079b4SArtur Paszkiewicz TEST_BIT(15, 7),
30f1b079b4SArtur Paszkiewicz TEST_BIT(42, 6),
31f1b079b4SArtur Paszkiewicz TEST_BIT(BITMAP_SIZE - 1, 0),
32f1b079b4SArtur Paszkiewicz TEST_BIT(BITMAP_SIZE - 1, 7),
33f1b079b4SArtur Paszkiewicz };
34f1b079b4SArtur Paszkiewicz static const size_t g_test_bits_count = sizeof(g_test_bits) / sizeof(*g_test_bits);
35f1b079b4SArtur Paszkiewicz
36f1b079b4SArtur Paszkiewicz static unsigned long g_buf[BITMAP_SIZE / sizeof(unsigned long)];
37f1b079b4SArtur Paszkiewicz static struct ftl_bitmap *g_bitmap;
38f1b079b4SArtur Paszkiewicz
39f1b079b4SArtur Paszkiewicz static uint64_t
count_set_bits(const struct ftl_bitmap * bitmap)40f1b079b4SArtur Paszkiewicz count_set_bits(const struct ftl_bitmap *bitmap)
41f1b079b4SArtur Paszkiewicz {
42f1b079b4SArtur Paszkiewicz uint64_t n = 0;
43f1b079b4SArtur Paszkiewicz uint64_t i;
44f1b079b4SArtur Paszkiewicz
45f1b079b4SArtur Paszkiewicz for (i = 0; i < BITMAP_CAPACITY; i++) {
46f1b079b4SArtur Paszkiewicz if (ftl_bitmap_get(bitmap, i)) {
47f1b079b4SArtur Paszkiewicz n++;
48f1b079b4SArtur Paszkiewicz }
49f1b079b4SArtur Paszkiewicz }
50f1b079b4SArtur Paszkiewicz
51f1b079b4SArtur Paszkiewicz return n;
52f1b079b4SArtur Paszkiewicz }
53f1b079b4SArtur Paszkiewicz
54f1b079b4SArtur Paszkiewicz static void
test_ftl_bitmap_create(void)55f1b079b4SArtur Paszkiewicz test_ftl_bitmap_create(void)
56f1b079b4SArtur Paszkiewicz {
57f1b079b4SArtur Paszkiewicz struct ftl_bitmap *ret;
58f1b079b4SArtur Paszkiewicz
59f1b079b4SArtur Paszkiewicz /* unaligned buffer */
60f1b079b4SArtur Paszkiewicz ret = ftl_bitmap_create(((uint8_t *)g_buf) + 1, BITMAP_SIZE);
61f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(ret, NULL);
62f1b079b4SArtur Paszkiewicz
63f1b079b4SArtur Paszkiewicz /* wrong size */
64f1b079b4SArtur Paszkiewicz ret = ftl_bitmap_create(g_buf, BITMAP_SIZE - 1);
65f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(ret, NULL);
66f1b079b4SArtur Paszkiewicz }
67f1b079b4SArtur Paszkiewicz
68f1b079b4SArtur Paszkiewicz static void
test_ftl_bitmap_get(void)69f1b079b4SArtur Paszkiewicz test_ftl_bitmap_get(void)
70f1b079b4SArtur Paszkiewicz {
71f1b079b4SArtur Paszkiewicz uint8_t *buf = (uint8_t *)g_buf;
72f1b079b4SArtur Paszkiewicz size_t i;
73f1b079b4SArtur Paszkiewicz
74f1b079b4SArtur Paszkiewicz memset(g_buf, 0, BITMAP_SIZE);
75f1b079b4SArtur Paszkiewicz
76f1b079b4SArtur Paszkiewicz for (i = 0; i < g_test_bits_count; i++) {
77f1b079b4SArtur Paszkiewicz buf[g_test_bits[i].byte_idx] += (1 << g_test_bits[i].byte_bit_idx);
78f1b079b4SArtur Paszkiewicz }
79f1b079b4SArtur Paszkiewicz
80f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(count_set_bits(g_bitmap), g_test_bits_count);
81f1b079b4SArtur Paszkiewicz
82f1b079b4SArtur Paszkiewicz for (i = 0; i < g_test_bits_count; i++) {
83f1b079b4SArtur Paszkiewicz CU_ASSERT_TRUE(ftl_bitmap_get(g_bitmap, g_test_bits[i].bit_idx));
84f1b079b4SArtur Paszkiewicz }
85f1b079b4SArtur Paszkiewicz }
86f1b079b4SArtur Paszkiewicz
87f1b079b4SArtur Paszkiewicz static void
test_ftl_bitmap_set(void)88f1b079b4SArtur Paszkiewicz test_ftl_bitmap_set(void)
89f1b079b4SArtur Paszkiewicz {
90f1b079b4SArtur Paszkiewicz size_t i;
91f1b079b4SArtur Paszkiewicz
92f1b079b4SArtur Paszkiewicz memset(g_buf, 0, BITMAP_SIZE);
93f1b079b4SArtur Paszkiewicz
94f1b079b4SArtur Paszkiewicz for (i = 0; i < g_test_bits_count; i++) {
95f1b079b4SArtur Paszkiewicz ftl_bitmap_set(g_bitmap, g_test_bits[i].bit_idx);
96f1b079b4SArtur Paszkiewicz }
97f1b079b4SArtur Paszkiewicz
98f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(count_set_bits(g_bitmap), g_test_bits_count);
99f1b079b4SArtur Paszkiewicz
100f1b079b4SArtur Paszkiewicz for (i = 0; i < g_test_bits_count; i++) {
101f1b079b4SArtur Paszkiewicz CU_ASSERT_TRUE(ftl_bitmap_get(g_bitmap, g_test_bits[i].bit_idx));
102f1b079b4SArtur Paszkiewicz }
103f1b079b4SArtur Paszkiewicz }
104f1b079b4SArtur Paszkiewicz
105f1b079b4SArtur Paszkiewicz static void
test_ftl_bitmap_clear(void)106f1b079b4SArtur Paszkiewicz test_ftl_bitmap_clear(void)
107f1b079b4SArtur Paszkiewicz {
108f1b079b4SArtur Paszkiewicz size_t i;
109f1b079b4SArtur Paszkiewicz
110f1b079b4SArtur Paszkiewicz memset(g_buf, 0xff, BITMAP_SIZE);
111f1b079b4SArtur Paszkiewicz
112f1b079b4SArtur Paszkiewicz for (i = 0; i < g_test_bits_count; i++) {
113f1b079b4SArtur Paszkiewicz ftl_bitmap_clear(g_bitmap, g_test_bits[i].bit_idx);
114f1b079b4SArtur Paszkiewicz }
115f1b079b4SArtur Paszkiewicz
116f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(count_set_bits(g_bitmap), BITMAP_CAPACITY - g_test_bits_count);
117f1b079b4SArtur Paszkiewicz
118f1b079b4SArtur Paszkiewicz for (i = 0; i < g_test_bits_count; i++) {
119f1b079b4SArtur Paszkiewicz CU_ASSERT_FALSE(ftl_bitmap_get(g_bitmap, g_test_bits[i].bit_idx));
120f1b079b4SArtur Paszkiewicz }
121f1b079b4SArtur Paszkiewicz }
122f1b079b4SArtur Paszkiewicz
123f1b079b4SArtur Paszkiewicz static void
test_ftl_bitmap_find_first_set(void)124f1b079b4SArtur Paszkiewicz test_ftl_bitmap_find_first_set(void)
125f1b079b4SArtur Paszkiewicz {
126f1b079b4SArtur Paszkiewicz size_t i;
127f1b079b4SArtur Paszkiewicz uint64_t bit;
128f1b079b4SArtur Paszkiewicz
129f1b079b4SArtur Paszkiewicz memset(g_buf, 0, BITMAP_SIZE);
130f1b079b4SArtur Paszkiewicz
131f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(ftl_bitmap_find_first_set(g_bitmap, 0, UINT64_MAX), UINT64_MAX);
132f1b079b4SArtur Paszkiewicz
133f1b079b4SArtur Paszkiewicz for (i = 1; i <= g_test_bits_count; i++) {
134f1b079b4SArtur Paszkiewicz bit = g_test_bits[g_test_bits_count - i].bit_idx;
135f1b079b4SArtur Paszkiewicz
136f1b079b4SArtur Paszkiewicz ftl_bitmap_set(g_bitmap, bit);
137f1b079b4SArtur Paszkiewicz
138f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(ftl_bitmap_find_first_set(g_bitmap, 0, UINT64_MAX), bit);
139f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(ftl_bitmap_find_first_set(g_bitmap, 0, bit), bit);
140f1b079b4SArtur Paszkiewicz if (bit > 0) {
141f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(ftl_bitmap_find_first_set(g_bitmap, 0, bit - 1), UINT64_MAX);
142f1b079b4SArtur Paszkiewicz }
143f1b079b4SArtur Paszkiewicz }
144f1b079b4SArtur Paszkiewicz
145f1b079b4SArtur Paszkiewicz for (i = 0; i < g_test_bits_count; i++) {
146f1b079b4SArtur Paszkiewicz bit = g_test_bits[i].bit_idx;
147f1b079b4SArtur Paszkiewicz
148f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(ftl_bitmap_find_first_set(g_bitmap, bit, UINT64_MAX), bit);
149f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(ftl_bitmap_find_first_set(g_bitmap, bit, bit), bit);
150f1b079b4SArtur Paszkiewicz }
151f1b079b4SArtur Paszkiewicz }
152f1b079b4SArtur Paszkiewicz
153f1b079b4SArtur Paszkiewicz static void
test_ftl_bitmap_find_first_clear(void)154f1b079b4SArtur Paszkiewicz test_ftl_bitmap_find_first_clear(void)
155f1b079b4SArtur Paszkiewicz {
156f1b079b4SArtur Paszkiewicz size_t i;
157f1b079b4SArtur Paszkiewicz uint64_t bit;
158f1b079b4SArtur Paszkiewicz
159f1b079b4SArtur Paszkiewicz memset(g_buf, 0xff, BITMAP_SIZE);
160f1b079b4SArtur Paszkiewicz
161f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(ftl_bitmap_find_first_clear(g_bitmap, 0, UINT64_MAX), UINT64_MAX);
162f1b079b4SArtur Paszkiewicz
163f1b079b4SArtur Paszkiewicz for (i = 1; i <= g_test_bits_count; i++) {
164f1b079b4SArtur Paszkiewicz bit = g_test_bits[g_test_bits_count - i].bit_idx;
165f1b079b4SArtur Paszkiewicz
166f1b079b4SArtur Paszkiewicz ftl_bitmap_clear(g_bitmap, bit);
167f1b079b4SArtur Paszkiewicz
168f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(ftl_bitmap_find_first_clear(g_bitmap, 0, UINT64_MAX), bit);
169f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(ftl_bitmap_find_first_clear(g_bitmap, 0, bit), bit);
170f1b079b4SArtur Paszkiewicz if (bit > 0) {
171f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(ftl_bitmap_find_first_clear(g_bitmap, 0, bit - 1), UINT64_MAX);
172f1b079b4SArtur Paszkiewicz }
173f1b079b4SArtur Paszkiewicz }
174f1b079b4SArtur Paszkiewicz
175f1b079b4SArtur Paszkiewicz for (i = 0; i < g_test_bits_count; i++) {
176f1b079b4SArtur Paszkiewicz bit = g_test_bits[i].bit_idx;
177f1b079b4SArtur Paszkiewicz
178f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(ftl_bitmap_find_first_clear(g_bitmap, bit, UINT64_MAX), bit);
179f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(ftl_bitmap_find_first_clear(g_bitmap, bit, bit), bit);
180f1b079b4SArtur Paszkiewicz }
181f1b079b4SArtur Paszkiewicz }
182f1b079b4SArtur Paszkiewicz
183f1b079b4SArtur Paszkiewicz static void
test_ftl_bitmap_count_set(void)184f1b079b4SArtur Paszkiewicz test_ftl_bitmap_count_set(void)
185f1b079b4SArtur Paszkiewicz {
186f1b079b4SArtur Paszkiewicz size_t i;
187f1b079b4SArtur Paszkiewicz
188f1b079b4SArtur Paszkiewicz memset(g_buf, 0, BITMAP_SIZE);
189f1b079b4SArtur Paszkiewicz
190f1b079b4SArtur Paszkiewicz for (i = 0; i < g_test_bits_count; i++) {
191f1b079b4SArtur Paszkiewicz ftl_bitmap_set(g_bitmap, g_test_bits[i].bit_idx);
192f1b079b4SArtur Paszkiewicz }
193f1b079b4SArtur Paszkiewicz
194f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(g_test_bits_count, ftl_bitmap_count_set(g_bitmap));
195f1b079b4SArtur Paszkiewicz CU_ASSERT_EQUAL(count_set_bits(g_bitmap), ftl_bitmap_count_set(g_bitmap));
196f1b079b4SArtur Paszkiewicz }
197f1b079b4SArtur Paszkiewicz
198f1b079b4SArtur Paszkiewicz static int
test_setup(void)199f1b079b4SArtur Paszkiewicz test_setup(void)
200f1b079b4SArtur Paszkiewicz {
201f1b079b4SArtur Paszkiewicz g_bitmap = ftl_bitmap_create(g_buf, BITMAP_SIZE);
202f1b079b4SArtur Paszkiewicz if (!g_bitmap) {
203f1b079b4SArtur Paszkiewicz return -ENOMEM;
204f1b079b4SArtur Paszkiewicz }
205f1b079b4SArtur Paszkiewicz
206f1b079b4SArtur Paszkiewicz return 0;
207f1b079b4SArtur Paszkiewicz }
208f1b079b4SArtur Paszkiewicz
209f1b079b4SArtur Paszkiewicz static int
test_cleanup(void)210f1b079b4SArtur Paszkiewicz test_cleanup(void)
211f1b079b4SArtur Paszkiewicz {
212f1b079b4SArtur Paszkiewicz free(g_bitmap);
213f1b079b4SArtur Paszkiewicz g_bitmap = NULL;
214f1b079b4SArtur Paszkiewicz return 0;
215f1b079b4SArtur Paszkiewicz }
216f1b079b4SArtur Paszkiewicz
217f1b079b4SArtur Paszkiewicz int
main(int argc,char ** argv)218f1b079b4SArtur Paszkiewicz main(int argc, char **argv)
219f1b079b4SArtur Paszkiewicz {
220f1b079b4SArtur Paszkiewicz CU_pSuite suite = NULL;
221f1b079b4SArtur Paszkiewicz unsigned int num_failures;
222f1b079b4SArtur Paszkiewicz
223f1b079b4SArtur Paszkiewicz CU_initialize_registry();
224f1b079b4SArtur Paszkiewicz
225f1b079b4SArtur Paszkiewicz suite = CU_add_suite("ftl_bitmap", test_setup, test_cleanup);
226f1b079b4SArtur Paszkiewicz CU_ADD_TEST(suite, test_ftl_bitmap_create);
227f1b079b4SArtur Paszkiewicz CU_ADD_TEST(suite, test_ftl_bitmap_get);
228f1b079b4SArtur Paszkiewicz CU_ADD_TEST(suite, test_ftl_bitmap_set);
229f1b079b4SArtur Paszkiewicz CU_ADD_TEST(suite, test_ftl_bitmap_clear);
230f1b079b4SArtur Paszkiewicz CU_ADD_TEST(suite, test_ftl_bitmap_find_first_set);
231f1b079b4SArtur Paszkiewicz CU_ADD_TEST(suite, test_ftl_bitmap_find_first_clear);
232f1b079b4SArtur Paszkiewicz CU_ADD_TEST(suite, test_ftl_bitmap_count_set);
233f1b079b4SArtur Paszkiewicz
234*ea941caeSKonrad Sztyber num_failures = spdk_ut_run_tests(argc, argv, NULL);
235f1b079b4SArtur Paszkiewicz CU_cleanup_registry();
236f1b079b4SArtur Paszkiewicz
237f1b079b4SArtur Paszkiewicz return num_failures;
238f1b079b4SArtur Paszkiewicz }
239