xref: /dpdk/app/test/test_bitmap.c (revision 3d4e27fd7ff050d565c7450930c92fb945706518)
1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson  * Copyright(c) 2017 Cavium, Inc
3a9de470cSBruce Richardson  */
4a9de470cSBruce Richardson 
5a9de470cSBruce Richardson #include <stdio.h>
6a9de470cSBruce Richardson #include <inttypes.h>
7a9de470cSBruce Richardson 
8a9de470cSBruce Richardson #include <rte_common.h>
9a9de470cSBruce Richardson #include <rte_bitmap.h>
10a9de470cSBruce Richardson #include <rte_malloc.h>
11a9de470cSBruce Richardson 
12a9de470cSBruce Richardson #include "test.h"
13a9de470cSBruce Richardson 
14a9de470cSBruce Richardson #define MAX_BITS 1000
15a9de470cSBruce Richardson 
16a9de470cSBruce Richardson static int
test_bitmap_scan_operations(struct rte_bitmap * bmp)17a9de470cSBruce Richardson test_bitmap_scan_operations(struct rte_bitmap *bmp)
18a9de470cSBruce Richardson {
19a9de470cSBruce Richardson 	uint64_t slab1_magic = 0xBADC0FFEEBADF00D;
20a9de470cSBruce Richardson 	uint64_t slab2_magic = 0xFEEDDEADDEADF00D;
215e9647fdSNithin Dabilpuram 	uint32_t pos = 0, start_pos;
225e9647fdSNithin Dabilpuram 	int i, nb_clear, nb_set;
23a9de470cSBruce Richardson 	uint64_t out_slab = 0;
24a9de470cSBruce Richardson 
25a9de470cSBruce Richardson 	rte_bitmap_reset(bmp);
26a9de470cSBruce Richardson 
27a9de470cSBruce Richardson 	rte_bitmap_set_slab(bmp, pos, slab1_magic);
28a9de470cSBruce Richardson 	rte_bitmap_set_slab(bmp, pos + RTE_BITMAP_SLAB_BIT_SIZE, slab2_magic);
29a9de470cSBruce Richardson 
30a9de470cSBruce Richardson 	if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
31a9de470cSBruce Richardson 		printf("Failed to get slab from bitmap.\n");
32a9de470cSBruce Richardson 		return TEST_FAILED;
33a9de470cSBruce Richardson 	}
34a9de470cSBruce Richardson 
35a9de470cSBruce Richardson 	if (slab1_magic != out_slab) {
36a9de470cSBruce Richardson 		printf("Scan operation sanity failed.\n");
37a9de470cSBruce Richardson 		return TEST_FAILED;
38a9de470cSBruce Richardson 	}
39a9de470cSBruce Richardson 
40a9de470cSBruce Richardson 	if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
41a9de470cSBruce Richardson 		printf("Failed to get slab from bitmap.\n");
42a9de470cSBruce Richardson 		return TEST_FAILED;
43a9de470cSBruce Richardson 	}
44a9de470cSBruce Richardson 
45a9de470cSBruce Richardson 	if (slab2_magic != out_slab) {
46a9de470cSBruce Richardson 		printf("Scan operation sanity failed.\n");
47a9de470cSBruce Richardson 		return TEST_FAILED;
48a9de470cSBruce Richardson 	}
49a9de470cSBruce Richardson 
50a9de470cSBruce Richardson 	/* Wrap around */
51a9de470cSBruce Richardson 	if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
52a9de470cSBruce Richardson 		printf("Failed to get slab from bitmap.\n");
53a9de470cSBruce Richardson 		return TEST_FAILED;
54a9de470cSBruce Richardson 	}
55a9de470cSBruce Richardson 
56a9de470cSBruce Richardson 	if (slab1_magic != out_slab) {
57a9de470cSBruce Richardson 		printf("Scan operation wrap around failed.\n");
58a9de470cSBruce Richardson 		return TEST_FAILED;
59a9de470cSBruce Richardson 	}
60a9de470cSBruce Richardson 
61a9de470cSBruce Richardson 	/* Scan reset check. */
62a9de470cSBruce Richardson 	__rte_bitmap_scan_init(bmp);
63a9de470cSBruce Richardson 
64a9de470cSBruce Richardson 	if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
65a9de470cSBruce Richardson 		printf("Failed to get slab from bitmap.\n");
66a9de470cSBruce Richardson 		return TEST_FAILED;
67a9de470cSBruce Richardson 	}
68a9de470cSBruce Richardson 
69a9de470cSBruce Richardson 	if (slab1_magic != out_slab) {
70a9de470cSBruce Richardson 		printf("Scan reset operation failed.\n");
71a9de470cSBruce Richardson 		return TEST_FAILED;
72a9de470cSBruce Richardson 	}
73a9de470cSBruce Richardson 
745e9647fdSNithin Dabilpuram 	/* Test scan when a cline is half full */
755e9647fdSNithin Dabilpuram 	rte_bitmap_reset(bmp);
765e9647fdSNithin Dabilpuram 	for (i = 0; i < MAX_BITS; i++)
775e9647fdSNithin Dabilpuram 		rte_bitmap_set(bmp, i);
785e9647fdSNithin Dabilpuram 
795e9647fdSNithin Dabilpuram 	nb_clear = RTE_MIN(RTE_BITMAP_CL_BIT_SIZE / 2, MAX_BITS);
805e9647fdSNithin Dabilpuram 	for (i = 0; i < nb_clear; i++)
815e9647fdSNithin Dabilpuram 		rte_bitmap_clear(bmp, i);
825e9647fdSNithin Dabilpuram 
835e9647fdSNithin Dabilpuram 	/* Find remaining bits set in bmp */
845e9647fdSNithin Dabilpuram 	__rte_bitmap_scan_init(bmp);
855e9647fdSNithin Dabilpuram 
865e9647fdSNithin Dabilpuram 	if (rte_bitmap_scan(bmp, &pos, &out_slab) != 1) {
875e9647fdSNithin Dabilpuram 		printf("Initial scan failed with half CL empty.\n");
885e9647fdSNithin Dabilpuram 		return TEST_FAILED;
895e9647fdSNithin Dabilpuram 	}
905e9647fdSNithin Dabilpuram 
915e9647fdSNithin Dabilpuram 	start_pos = pos;
925e9647fdSNithin Dabilpuram 	nb_set = 0;
935e9647fdSNithin Dabilpuram 	do {
94*3d4e27fdSDavid Marchand 		nb_set += rte_popcount64(out_slab);
955e9647fdSNithin Dabilpuram 		if (!rte_bitmap_scan(bmp, &pos, &out_slab))
965e9647fdSNithin Dabilpuram 			break;
975e9647fdSNithin Dabilpuram 	} while (pos != start_pos);
985e9647fdSNithin Dabilpuram 
995e9647fdSNithin Dabilpuram 	if ((nb_clear + nb_set) != MAX_BITS) {
1005e9647fdSNithin Dabilpuram 		printf("Scan failed to find all set bits. "
1015e9647fdSNithin Dabilpuram 		       "Expected %u, found %u.\n", MAX_BITS - nb_clear, nb_set);
1025e9647fdSNithin Dabilpuram 		return TEST_FAILED;
1035e9647fdSNithin Dabilpuram 	}
1045e9647fdSNithin Dabilpuram 
105a9de470cSBruce Richardson 	return TEST_SUCCESS;
106a9de470cSBruce Richardson }
107a9de470cSBruce Richardson 
108a9de470cSBruce Richardson static int
test_bitmap_slab_set_get(struct rte_bitmap * bmp)109a9de470cSBruce Richardson test_bitmap_slab_set_get(struct rte_bitmap *bmp)
110a9de470cSBruce Richardson {
111a9de470cSBruce Richardson 	uint32_t pos = 0;
112a9de470cSBruce Richardson 	uint64_t slab_magic = 0xBADC0FFEEBADF00D;
113a9de470cSBruce Richardson 	uint64_t out_slab = 0;
114a9de470cSBruce Richardson 
115a9de470cSBruce Richardson 	rte_bitmap_reset(bmp);
116a9de470cSBruce Richardson 	rte_bitmap_set_slab(bmp, pos, slab_magic);
117a9de470cSBruce Richardson 
118a9de470cSBruce Richardson 	if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
119a9de470cSBruce Richardson 		printf("Failed to get slab from bitmap.\n");
120a9de470cSBruce Richardson 		return TEST_FAILED;
121a9de470cSBruce Richardson 	}
122a9de470cSBruce Richardson 
123a9de470cSBruce Richardson 
124a9de470cSBruce Richardson 	if (slab_magic != out_slab) {
125a9de470cSBruce Richardson 		printf("Invalid slab in bitmap.\n");
126a9de470cSBruce Richardson 		return TEST_FAILED;
127a9de470cSBruce Richardson 	}
128a9de470cSBruce Richardson 
129a9de470cSBruce Richardson 
130a9de470cSBruce Richardson 	return TEST_SUCCESS;
131a9de470cSBruce Richardson }
132a9de470cSBruce Richardson 
133a9de470cSBruce Richardson static int
test_bitmap_set_get_clear(struct rte_bitmap * bmp)134a9de470cSBruce Richardson test_bitmap_set_get_clear(struct rte_bitmap *bmp)
135a9de470cSBruce Richardson {
136a9de470cSBruce Richardson 	uint64_t val;
137a9de470cSBruce Richardson 	int i;
138a9de470cSBruce Richardson 
139a9de470cSBruce Richardson 	rte_bitmap_reset(bmp);
140a9de470cSBruce Richardson 	for (i = 0; i < MAX_BITS; i++)
141a9de470cSBruce Richardson 		rte_bitmap_set(bmp, i);
142a9de470cSBruce Richardson 
143a9de470cSBruce Richardson 	for (i = 0; i < MAX_BITS; i++) {
144a9de470cSBruce Richardson 		if (!rte_bitmap_get(bmp, i)) {
145a9de470cSBruce Richardson 			printf("Failed to get set bit.\n");
146a9de470cSBruce Richardson 			return TEST_FAILED;
147a9de470cSBruce Richardson 		}
148a9de470cSBruce Richardson 	}
149a9de470cSBruce Richardson 
150a9de470cSBruce Richardson 	for (i = 0; i < MAX_BITS; i++)
151a9de470cSBruce Richardson 		rte_bitmap_clear(bmp, i);
152a9de470cSBruce Richardson 
153a9de470cSBruce Richardson 	for (i = 0; i < MAX_BITS; i++) {
154a9de470cSBruce Richardson 		if (rte_bitmap_get(bmp, i)) {
155a9de470cSBruce Richardson 			printf("Failed to clear set bit.\n");
156a9de470cSBruce Richardson 			return TEST_FAILED;
157a9de470cSBruce Richardson 		}
158a9de470cSBruce Richardson 	}
159a9de470cSBruce Richardson 
160a9de470cSBruce Richardson 	rte_bitmap_reset(bmp);
161a9de470cSBruce Richardson 
162a9de470cSBruce Richardson 	/* Alternate slab set test */
163a9de470cSBruce Richardson 	for (i = 0; i < MAX_BITS; i++) {
164a9de470cSBruce Richardson 		if (i % RTE_BITMAP_SLAB_BIT_SIZE)
165a9de470cSBruce Richardson 			rte_bitmap_set(bmp, i);
166a9de470cSBruce Richardson 	}
167a9de470cSBruce Richardson 
168a9de470cSBruce Richardson 	for (i = 0; i < MAX_BITS; i++) {
169a9de470cSBruce Richardson 		val = rte_bitmap_get(bmp, i);
170a9de470cSBruce Richardson 		if (((i % RTE_BITMAP_SLAB_BIT_SIZE) && !val) ||
171a9de470cSBruce Richardson 		    (!(i % RTE_BITMAP_SLAB_BIT_SIZE) && val)) {
172a9de470cSBruce Richardson 			printf("Failed to get set bit.\n");
173a9de470cSBruce Richardson 			return TEST_FAILED;
174a9de470cSBruce Richardson 		}
175a9de470cSBruce Richardson 	}
176a9de470cSBruce Richardson 
177a9de470cSBruce Richardson 	return TEST_SUCCESS;
178a9de470cSBruce Richardson }
179a9de470cSBruce Richardson 
180a9de470cSBruce Richardson static int
test_bitmap_all_clear(void)181fc202a6fSSuanming Mou test_bitmap_all_clear(void)
182a9de470cSBruce Richardson {
183a9de470cSBruce Richardson 	void *mem;
184a9de470cSBruce Richardson 	uint32_t bmp_size;
185a9de470cSBruce Richardson 	struct rte_bitmap *bmp;
186a9de470cSBruce Richardson 
187a9de470cSBruce Richardson 	bmp_size =
188a9de470cSBruce Richardson 		rte_bitmap_get_memory_footprint(MAX_BITS);
189a9de470cSBruce Richardson 
190a9de470cSBruce Richardson 	mem = rte_zmalloc("test_bmap", bmp_size, RTE_CACHE_LINE_SIZE);
191a9de470cSBruce Richardson 	if (mem == NULL) {
192a9de470cSBruce Richardson 		printf("Failed to allocate memory for bitmap\n");
193a9de470cSBruce Richardson 		return TEST_FAILED;
194a9de470cSBruce Richardson 	}
195a9de470cSBruce Richardson 
196a9de470cSBruce Richardson 	bmp = rte_bitmap_init(MAX_BITS, mem, bmp_size);
197a9de470cSBruce Richardson 	if (bmp == NULL) {
198a9de470cSBruce Richardson 		printf("Failed to init bitmap\n");
199a9de470cSBruce Richardson 		return TEST_FAILED;
200a9de470cSBruce Richardson 	}
201a9de470cSBruce Richardson 
202a9de470cSBruce Richardson 	if (test_bitmap_set_get_clear(bmp) < 0)
203a9de470cSBruce Richardson 		return TEST_FAILED;
204a9de470cSBruce Richardson 
205a9de470cSBruce Richardson 	if (test_bitmap_slab_set_get(bmp) < 0)
206a9de470cSBruce Richardson 		return TEST_FAILED;
207a9de470cSBruce Richardson 
208a9de470cSBruce Richardson 	if (test_bitmap_scan_operations(bmp) < 0)
209a9de470cSBruce Richardson 		return TEST_FAILED;
210a9de470cSBruce Richardson 
211a9de470cSBruce Richardson 	rte_bitmap_free(bmp);
212a9de470cSBruce Richardson 	rte_free(mem);
213a9de470cSBruce Richardson 
214a9de470cSBruce Richardson 	return TEST_SUCCESS;
215a9de470cSBruce Richardson }
216a9de470cSBruce Richardson 
217fc202a6fSSuanming Mou static int
test_bitmap_all_set(void)218fc202a6fSSuanming Mou test_bitmap_all_set(void)
219fc202a6fSSuanming Mou {
220fc202a6fSSuanming Mou 	void *mem;
221fc202a6fSSuanming Mou 	uint32_t i;
222fc202a6fSSuanming Mou 	uint64_t slab;
223fc202a6fSSuanming Mou 	uint32_t pos;
224fc202a6fSSuanming Mou 	uint32_t bmp_size;
225fc202a6fSSuanming Mou 	struct rte_bitmap *bmp;
226fc202a6fSSuanming Mou 
227fc202a6fSSuanming Mou 	bmp_size =
228fc202a6fSSuanming Mou 		rte_bitmap_get_memory_footprint(MAX_BITS);
229fc202a6fSSuanming Mou 
230fc202a6fSSuanming Mou 	mem = rte_zmalloc("test_bmap", bmp_size, RTE_CACHE_LINE_SIZE);
231fc202a6fSSuanming Mou 	if (mem == NULL) {
232fc202a6fSSuanming Mou 		printf("Failed to allocate memory for bitmap\n");
233fc202a6fSSuanming Mou 		return TEST_FAILED;
234fc202a6fSSuanming Mou 	}
235fc202a6fSSuanming Mou 
236fc202a6fSSuanming Mou 	bmp = rte_bitmap_init_with_all_set(MAX_BITS, mem, bmp_size);
237fc202a6fSSuanming Mou 	if (bmp == NULL) {
238fc202a6fSSuanming Mou 		printf("Failed to init bitmap\n");
239fc202a6fSSuanming Mou 		return TEST_FAILED;
240fc202a6fSSuanming Mou 	}
241fc202a6fSSuanming Mou 
242fc202a6fSSuanming Mou 	for (i = 0; i < MAX_BITS; i++) {
243fc202a6fSSuanming Mou 		pos = slab = 0;
244fc202a6fSSuanming Mou 		if (!rte_bitmap_scan(bmp, &pos, &slab)) {
245fc202a6fSSuanming Mou 			printf("Failed with init bitmap.\n");
246fc202a6fSSuanming Mou 			return TEST_FAILED;
247fc202a6fSSuanming Mou 		}
248*3d4e27fdSDavid Marchand 		pos += (slab ? rte_ctz64(slab) : 0);
249fc202a6fSSuanming Mou 		rte_bitmap_clear(bmp, pos);
250fc202a6fSSuanming Mou 	}
251fc202a6fSSuanming Mou 
252fc202a6fSSuanming Mou 	if (rte_bitmap_scan(bmp, &pos, &slab)) {
253fc202a6fSSuanming Mou 		printf("Too much bits set.\n");
254fc202a6fSSuanming Mou 		return TEST_FAILED;
255fc202a6fSSuanming Mou 	}
256fc202a6fSSuanming Mou 
257fc202a6fSSuanming Mou 	rte_bitmap_free(bmp);
258fc202a6fSSuanming Mou 	rte_free(mem);
259fc202a6fSSuanming Mou 
260fc202a6fSSuanming Mou 	return TEST_SUCCESS;
261fc202a6fSSuanming Mou 
262fc202a6fSSuanming Mou }
263fc202a6fSSuanming Mou 
264fc202a6fSSuanming Mou static int
test_bitmap(void)265fc202a6fSSuanming Mou test_bitmap(void)
266fc202a6fSSuanming Mou {
267fc202a6fSSuanming Mou 	if (test_bitmap_all_clear() != TEST_SUCCESS)
268fc202a6fSSuanming Mou 		return TEST_FAILED;
269fc202a6fSSuanming Mou 	return test_bitmap_all_set();
270fc202a6fSSuanming Mou }
271fc202a6fSSuanming Mou 
272e0a8442cSBruce Richardson REGISTER_FAST_TEST(bitmap_autotest, true, true, test_bitmap);
273