14418919fSjohnjiang /* SPDX-License-Identifier: BSD-3-Clause
24418919fSjohnjiang * Copyright(c) 2017 Cavium, Inc
34418919fSjohnjiang */
44418919fSjohnjiang
54418919fSjohnjiang #include <stdio.h>
64418919fSjohnjiang #include <inttypes.h>
74418919fSjohnjiang
84418919fSjohnjiang #include <rte_common.h>
94418919fSjohnjiang #include <rte_bitmap.h>
104418919fSjohnjiang #include <rte_malloc.h>
114418919fSjohnjiang
124418919fSjohnjiang #include "test.h"
134418919fSjohnjiang
144418919fSjohnjiang #define MAX_BITS 1000
154418919fSjohnjiang
164418919fSjohnjiang static int
test_bitmap_scan_operations(struct rte_bitmap * bmp)174418919fSjohnjiang test_bitmap_scan_operations(struct rte_bitmap *bmp)
184418919fSjohnjiang {
194418919fSjohnjiang uint32_t pos = 0;
204418919fSjohnjiang uint64_t slab1_magic = 0xBADC0FFEEBADF00D;
214418919fSjohnjiang uint64_t slab2_magic = 0xFEEDDEADDEADF00D;
224418919fSjohnjiang uint64_t out_slab = 0;
234418919fSjohnjiang
244418919fSjohnjiang rte_bitmap_reset(bmp);
254418919fSjohnjiang
264418919fSjohnjiang rte_bitmap_set_slab(bmp, pos, slab1_magic);
274418919fSjohnjiang rte_bitmap_set_slab(bmp, pos + RTE_BITMAP_SLAB_BIT_SIZE, slab2_magic);
284418919fSjohnjiang
294418919fSjohnjiang if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
304418919fSjohnjiang printf("Failed to get slab from bitmap.\n");
314418919fSjohnjiang return TEST_FAILED;
324418919fSjohnjiang }
334418919fSjohnjiang
344418919fSjohnjiang if (slab1_magic != out_slab) {
354418919fSjohnjiang printf("Scan operation sanity failed.\n");
364418919fSjohnjiang return TEST_FAILED;
374418919fSjohnjiang }
384418919fSjohnjiang
394418919fSjohnjiang if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
404418919fSjohnjiang printf("Failed to get slab from bitmap.\n");
414418919fSjohnjiang return TEST_FAILED;
424418919fSjohnjiang }
434418919fSjohnjiang
444418919fSjohnjiang if (slab2_magic != out_slab) {
454418919fSjohnjiang printf("Scan operation sanity failed.\n");
464418919fSjohnjiang return TEST_FAILED;
474418919fSjohnjiang }
484418919fSjohnjiang
494418919fSjohnjiang /* Wrap around */
504418919fSjohnjiang if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
514418919fSjohnjiang printf("Failed to get slab from bitmap.\n");
524418919fSjohnjiang return TEST_FAILED;
534418919fSjohnjiang }
544418919fSjohnjiang
554418919fSjohnjiang if (slab1_magic != out_slab) {
564418919fSjohnjiang printf("Scan operation wrap around failed.\n");
574418919fSjohnjiang return TEST_FAILED;
584418919fSjohnjiang }
594418919fSjohnjiang
604418919fSjohnjiang /* Scan reset check. */
614418919fSjohnjiang __rte_bitmap_scan_init(bmp);
624418919fSjohnjiang
634418919fSjohnjiang if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
644418919fSjohnjiang printf("Failed to get slab from bitmap.\n");
654418919fSjohnjiang return TEST_FAILED;
664418919fSjohnjiang }
674418919fSjohnjiang
684418919fSjohnjiang if (slab1_magic != out_slab) {
694418919fSjohnjiang printf("Scan reset operation failed.\n");
704418919fSjohnjiang return TEST_FAILED;
714418919fSjohnjiang }
724418919fSjohnjiang
734418919fSjohnjiang return TEST_SUCCESS;
744418919fSjohnjiang }
754418919fSjohnjiang
764418919fSjohnjiang static int
test_bitmap_slab_set_get(struct rte_bitmap * bmp)774418919fSjohnjiang test_bitmap_slab_set_get(struct rte_bitmap *bmp)
784418919fSjohnjiang {
794418919fSjohnjiang uint32_t pos = 0;
804418919fSjohnjiang uint64_t slab_magic = 0xBADC0FFEEBADF00D;
814418919fSjohnjiang uint64_t out_slab = 0;
824418919fSjohnjiang
834418919fSjohnjiang rte_bitmap_reset(bmp);
844418919fSjohnjiang rte_bitmap_set_slab(bmp, pos, slab_magic);
854418919fSjohnjiang
864418919fSjohnjiang if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
874418919fSjohnjiang printf("Failed to get slab from bitmap.\n");
884418919fSjohnjiang return TEST_FAILED;
894418919fSjohnjiang }
904418919fSjohnjiang
914418919fSjohnjiang
924418919fSjohnjiang if (slab_magic != out_slab) {
934418919fSjohnjiang printf("Invalid slab in bitmap.\n");
944418919fSjohnjiang return TEST_FAILED;
954418919fSjohnjiang }
964418919fSjohnjiang
974418919fSjohnjiang
984418919fSjohnjiang return TEST_SUCCESS;
994418919fSjohnjiang }
1004418919fSjohnjiang
1014418919fSjohnjiang static int
test_bitmap_set_get_clear(struct rte_bitmap * bmp)1024418919fSjohnjiang test_bitmap_set_get_clear(struct rte_bitmap *bmp)
1034418919fSjohnjiang {
1044418919fSjohnjiang uint64_t val;
1054418919fSjohnjiang int i;
1064418919fSjohnjiang
1074418919fSjohnjiang rte_bitmap_reset(bmp);
1084418919fSjohnjiang for (i = 0; i < MAX_BITS; i++)
1094418919fSjohnjiang rte_bitmap_set(bmp, i);
1104418919fSjohnjiang
1114418919fSjohnjiang for (i = 0; i < MAX_BITS; i++) {
1124418919fSjohnjiang if (!rte_bitmap_get(bmp, i)) {
1134418919fSjohnjiang printf("Failed to get set bit.\n");
1144418919fSjohnjiang return TEST_FAILED;
1154418919fSjohnjiang }
1164418919fSjohnjiang }
1174418919fSjohnjiang
1184418919fSjohnjiang for (i = 0; i < MAX_BITS; i++)
1194418919fSjohnjiang rte_bitmap_clear(bmp, i);
1204418919fSjohnjiang
1214418919fSjohnjiang for (i = 0; i < MAX_BITS; i++) {
1224418919fSjohnjiang if (rte_bitmap_get(bmp, i)) {
1234418919fSjohnjiang printf("Failed to clear set bit.\n");
1244418919fSjohnjiang return TEST_FAILED;
1254418919fSjohnjiang }
1264418919fSjohnjiang }
1274418919fSjohnjiang
1284418919fSjohnjiang rte_bitmap_reset(bmp);
1294418919fSjohnjiang
1304418919fSjohnjiang /* Alternate slab set test */
1314418919fSjohnjiang for (i = 0; i < MAX_BITS; i++) {
1324418919fSjohnjiang if (i % RTE_BITMAP_SLAB_BIT_SIZE)
1334418919fSjohnjiang rte_bitmap_set(bmp, i);
1344418919fSjohnjiang }
1354418919fSjohnjiang
1364418919fSjohnjiang for (i = 0; i < MAX_BITS; i++) {
1374418919fSjohnjiang val = rte_bitmap_get(bmp, i);
1384418919fSjohnjiang if (((i % RTE_BITMAP_SLAB_BIT_SIZE) && !val) ||
1394418919fSjohnjiang (!(i % RTE_BITMAP_SLAB_BIT_SIZE) && val)) {
1404418919fSjohnjiang printf("Failed to get set bit.\n");
1414418919fSjohnjiang return TEST_FAILED;
1424418919fSjohnjiang }
1434418919fSjohnjiang }
1444418919fSjohnjiang
1454418919fSjohnjiang return TEST_SUCCESS;
1464418919fSjohnjiang }
1474418919fSjohnjiang
1484418919fSjohnjiang static int
test_bitmap_all_clear(void)149*2d9fd380Sjfb8856606 test_bitmap_all_clear(void)
1504418919fSjohnjiang {
1514418919fSjohnjiang void *mem;
1524418919fSjohnjiang uint32_t bmp_size;
1534418919fSjohnjiang struct rte_bitmap *bmp;
1544418919fSjohnjiang
1554418919fSjohnjiang bmp_size =
1564418919fSjohnjiang rte_bitmap_get_memory_footprint(MAX_BITS);
1574418919fSjohnjiang
1584418919fSjohnjiang mem = rte_zmalloc("test_bmap", bmp_size, RTE_CACHE_LINE_SIZE);
1594418919fSjohnjiang if (mem == NULL) {
1604418919fSjohnjiang printf("Failed to allocate memory for bitmap\n");
1614418919fSjohnjiang return TEST_FAILED;
1624418919fSjohnjiang }
1634418919fSjohnjiang
1644418919fSjohnjiang bmp = rte_bitmap_init(MAX_BITS, mem, bmp_size);
1654418919fSjohnjiang if (bmp == NULL) {
1664418919fSjohnjiang printf("Failed to init bitmap\n");
1674418919fSjohnjiang return TEST_FAILED;
1684418919fSjohnjiang }
1694418919fSjohnjiang
1704418919fSjohnjiang if (test_bitmap_set_get_clear(bmp) < 0)
1714418919fSjohnjiang return TEST_FAILED;
1724418919fSjohnjiang
1734418919fSjohnjiang if (test_bitmap_slab_set_get(bmp) < 0)
1744418919fSjohnjiang return TEST_FAILED;
1754418919fSjohnjiang
1764418919fSjohnjiang if (test_bitmap_scan_operations(bmp) < 0)
1774418919fSjohnjiang return TEST_FAILED;
1784418919fSjohnjiang
1794418919fSjohnjiang rte_bitmap_free(bmp);
1804418919fSjohnjiang rte_free(mem);
1814418919fSjohnjiang
1824418919fSjohnjiang return TEST_SUCCESS;
1834418919fSjohnjiang }
1844418919fSjohnjiang
185*2d9fd380Sjfb8856606 static int
test_bitmap_all_set(void)186*2d9fd380Sjfb8856606 test_bitmap_all_set(void)
187*2d9fd380Sjfb8856606 {
188*2d9fd380Sjfb8856606 void *mem;
189*2d9fd380Sjfb8856606 uint32_t i;
190*2d9fd380Sjfb8856606 uint64_t slab;
191*2d9fd380Sjfb8856606 uint32_t pos;
192*2d9fd380Sjfb8856606 uint32_t bmp_size;
193*2d9fd380Sjfb8856606 struct rte_bitmap *bmp;
194*2d9fd380Sjfb8856606
195*2d9fd380Sjfb8856606 bmp_size =
196*2d9fd380Sjfb8856606 rte_bitmap_get_memory_footprint(MAX_BITS);
197*2d9fd380Sjfb8856606
198*2d9fd380Sjfb8856606 mem = rte_zmalloc("test_bmap", bmp_size, RTE_CACHE_LINE_SIZE);
199*2d9fd380Sjfb8856606 if (mem == NULL) {
200*2d9fd380Sjfb8856606 printf("Failed to allocate memory for bitmap\n");
201*2d9fd380Sjfb8856606 return TEST_FAILED;
202*2d9fd380Sjfb8856606 }
203*2d9fd380Sjfb8856606
204*2d9fd380Sjfb8856606 bmp = rte_bitmap_init_with_all_set(MAX_BITS, mem, bmp_size);
205*2d9fd380Sjfb8856606 if (bmp == NULL) {
206*2d9fd380Sjfb8856606 printf("Failed to init bitmap\n");
207*2d9fd380Sjfb8856606 return TEST_FAILED;
208*2d9fd380Sjfb8856606 }
209*2d9fd380Sjfb8856606
210*2d9fd380Sjfb8856606 for (i = 0; i < MAX_BITS; i++) {
211*2d9fd380Sjfb8856606 pos = slab = 0;
212*2d9fd380Sjfb8856606 if (!rte_bitmap_scan(bmp, &pos, &slab)) {
213*2d9fd380Sjfb8856606 printf("Failed with init bitmap.\n");
214*2d9fd380Sjfb8856606 return TEST_FAILED;
215*2d9fd380Sjfb8856606 }
216*2d9fd380Sjfb8856606 pos += (slab ? __builtin_ctzll(slab) : 0);
217*2d9fd380Sjfb8856606 rte_bitmap_clear(bmp, pos);
218*2d9fd380Sjfb8856606 }
219*2d9fd380Sjfb8856606
220*2d9fd380Sjfb8856606 if (rte_bitmap_scan(bmp, &pos, &slab)) {
221*2d9fd380Sjfb8856606 printf("Too much bits set.\n");
222*2d9fd380Sjfb8856606 return TEST_FAILED;
223*2d9fd380Sjfb8856606 }
224*2d9fd380Sjfb8856606
225*2d9fd380Sjfb8856606 rte_bitmap_free(bmp);
226*2d9fd380Sjfb8856606 rte_free(mem);
227*2d9fd380Sjfb8856606
228*2d9fd380Sjfb8856606 return TEST_SUCCESS;
229*2d9fd380Sjfb8856606
230*2d9fd380Sjfb8856606 }
231*2d9fd380Sjfb8856606
232*2d9fd380Sjfb8856606 static int
test_bitmap(void)233*2d9fd380Sjfb8856606 test_bitmap(void)
234*2d9fd380Sjfb8856606 {
235*2d9fd380Sjfb8856606 if (test_bitmap_all_clear() != TEST_SUCCESS)
236*2d9fd380Sjfb8856606 return TEST_FAILED;
237*2d9fd380Sjfb8856606 return test_bitmap_all_set();
238*2d9fd380Sjfb8856606 }
239*2d9fd380Sjfb8856606
2404418919fSjohnjiang REGISTER_TEST_COMMAND(bitmap_test, test_bitmap);
241