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 uint32_t pos = 0;
20 uint64_t slab1_magic = 0xBADC0FFEEBADF00D;
21 uint64_t slab2_magic = 0xFEEDDEADDEADF00D;
22 uint64_t out_slab = 0;
23
24 rte_bitmap_reset(bmp);
25
26 rte_bitmap_set_slab(bmp, pos, slab1_magic);
27 rte_bitmap_set_slab(bmp, pos + RTE_BITMAP_SLAB_BIT_SIZE, slab2_magic);
28
29 if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
30 printf("Failed to get slab from bitmap.\n");
31 return TEST_FAILED;
32 }
33
34 if (slab1_magic != out_slab) {
35 printf("Scan operation sanity failed.\n");
36 return TEST_FAILED;
37 }
38
39 if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
40 printf("Failed to get slab from bitmap.\n");
41 return TEST_FAILED;
42 }
43
44 if (slab2_magic != out_slab) {
45 printf("Scan operation sanity failed.\n");
46 return TEST_FAILED;
47 }
48
49 /* Wrap around */
50 if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
51 printf("Failed to get slab from bitmap.\n");
52 return TEST_FAILED;
53 }
54
55 if (slab1_magic != out_slab) {
56 printf("Scan operation wrap around failed.\n");
57 return TEST_FAILED;
58 }
59
60 /* Scan reset check. */
61 __rte_bitmap_scan_init(bmp);
62
63 if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
64 printf("Failed to get slab from bitmap.\n");
65 return TEST_FAILED;
66 }
67
68 if (slab1_magic != out_slab) {
69 printf("Scan reset operation failed.\n");
70 return TEST_FAILED;
71 }
72
73 return TEST_SUCCESS;
74 }
75
76 static int
test_bitmap_slab_set_get(struct rte_bitmap * bmp)77 test_bitmap_slab_set_get(struct rte_bitmap *bmp)
78 {
79 uint32_t pos = 0;
80 uint64_t slab_magic = 0xBADC0FFEEBADF00D;
81 uint64_t out_slab = 0;
82
83 rte_bitmap_reset(bmp);
84 rte_bitmap_set_slab(bmp, pos, slab_magic);
85
86 if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
87 printf("Failed to get slab from bitmap.\n");
88 return TEST_FAILED;
89 }
90
91
92 if (slab_magic != out_slab) {
93 printf("Invalid slab in bitmap.\n");
94 return TEST_FAILED;
95 }
96
97
98 return TEST_SUCCESS;
99 }
100
101 static int
test_bitmap_set_get_clear(struct rte_bitmap * bmp)102 test_bitmap_set_get_clear(struct rte_bitmap *bmp)
103 {
104 uint64_t val;
105 int i;
106
107 rte_bitmap_reset(bmp);
108 for (i = 0; i < MAX_BITS; i++)
109 rte_bitmap_set(bmp, i);
110
111 for (i = 0; i < MAX_BITS; i++) {
112 if (!rte_bitmap_get(bmp, i)) {
113 printf("Failed to get set bit.\n");
114 return TEST_FAILED;
115 }
116 }
117
118 for (i = 0; i < MAX_BITS; i++)
119 rte_bitmap_clear(bmp, i);
120
121 for (i = 0; i < MAX_BITS; i++) {
122 if (rte_bitmap_get(bmp, i)) {
123 printf("Failed to clear set bit.\n");
124 return TEST_FAILED;
125 }
126 }
127
128 rte_bitmap_reset(bmp);
129
130 /* Alternate slab set test */
131 for (i = 0; i < MAX_BITS; i++) {
132 if (i % RTE_BITMAP_SLAB_BIT_SIZE)
133 rte_bitmap_set(bmp, i);
134 }
135
136 for (i = 0; i < MAX_BITS; i++) {
137 val = rte_bitmap_get(bmp, i);
138 if (((i % RTE_BITMAP_SLAB_BIT_SIZE) && !val) ||
139 (!(i % RTE_BITMAP_SLAB_BIT_SIZE) && val)) {
140 printf("Failed to get set bit.\n");
141 return TEST_FAILED;
142 }
143 }
144
145 return TEST_SUCCESS;
146 }
147
148 static int
test_bitmap_all_clear(void)149 test_bitmap_all_clear(void)
150 {
151 void *mem;
152 uint32_t bmp_size;
153 struct rte_bitmap *bmp;
154
155 bmp_size =
156 rte_bitmap_get_memory_footprint(MAX_BITS);
157
158 mem = rte_zmalloc("test_bmap", bmp_size, RTE_CACHE_LINE_SIZE);
159 if (mem == NULL) {
160 printf("Failed to allocate memory for bitmap\n");
161 return TEST_FAILED;
162 }
163
164 bmp = rte_bitmap_init(MAX_BITS, mem, bmp_size);
165 if (bmp == NULL) {
166 printf("Failed to init bitmap\n");
167 return TEST_FAILED;
168 }
169
170 if (test_bitmap_set_get_clear(bmp) < 0)
171 return TEST_FAILED;
172
173 if (test_bitmap_slab_set_get(bmp) < 0)
174 return TEST_FAILED;
175
176 if (test_bitmap_scan_operations(bmp) < 0)
177 return TEST_FAILED;
178
179 rte_bitmap_free(bmp);
180 rte_free(mem);
181
182 return TEST_SUCCESS;
183 }
184
185 static int
test_bitmap_all_set(void)186 test_bitmap_all_set(void)
187 {
188 void *mem;
189 uint32_t i;
190 uint64_t slab;
191 uint32_t pos;
192 uint32_t bmp_size;
193 struct rte_bitmap *bmp;
194
195 bmp_size =
196 rte_bitmap_get_memory_footprint(MAX_BITS);
197
198 mem = rte_zmalloc("test_bmap", bmp_size, RTE_CACHE_LINE_SIZE);
199 if (mem == NULL) {
200 printf("Failed to allocate memory for bitmap\n");
201 return TEST_FAILED;
202 }
203
204 bmp = rte_bitmap_init_with_all_set(MAX_BITS, mem, bmp_size);
205 if (bmp == NULL) {
206 printf("Failed to init bitmap\n");
207 return TEST_FAILED;
208 }
209
210 for (i = 0; i < MAX_BITS; i++) {
211 pos = slab = 0;
212 if (!rte_bitmap_scan(bmp, &pos, &slab)) {
213 printf("Failed with init bitmap.\n");
214 return TEST_FAILED;
215 }
216 pos += (slab ? __builtin_ctzll(slab) : 0);
217 rte_bitmap_clear(bmp, pos);
218 }
219
220 if (rte_bitmap_scan(bmp, &pos, &slab)) {
221 printf("Too much bits set.\n");
222 return TEST_FAILED;
223 }
224
225 rte_bitmap_free(bmp);
226 rte_free(mem);
227
228 return TEST_SUCCESS;
229
230 }
231
232 static int
test_bitmap(void)233 test_bitmap(void)
234 {
235 if (test_bitmap_all_clear() != TEST_SUCCESS)
236 return TEST_FAILED;
237 return test_bitmap_all_set();
238 }
239
240 REGISTER_TEST_COMMAND(bitmap_test, test_bitmap);
241