bpf: allow self-xor operation
[dpdk.git] / app / test / test_bitmap.c
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 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 += __builtin_popcountll(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
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
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
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
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 ? __builtin_ctzll(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
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_TEST_COMMAND(bitmap_test, test_bitmap);