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