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