numam-dpdk/app/test/test_bitmap.c
Suanming Mou fc202a6f2a bitmap: add init with all bits set
Currently, in the case to use bitmap as resource allocator, after
bitmap creation, all the bitmap bits should be set to indicate the
bit available. Every time when allocate one bit, search for the set
bits and clear it to make it in use.

Add a new rte_bitmap_init_with_all_set() function to have a quick
fill up the bitmap bits.

Comparing with the case create the bitmap as empty and set the bitmap
one by one, the new function costs less cycles.

Signed-off-by: Suanming Mou <suanmingm@mellanox.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
2020-04-15 16:10:12 +02:00

241 lines
4.7 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2017 Cavium, Inc
*/
#include <stdio.h>
#include <inttypes.h>
#include <rte_common.h>
#include <rte_bitmap.h>
#include <rte_malloc.h>
#include "test.h"
#define MAX_BITS 1000
static int
test_bitmap_scan_operations(struct rte_bitmap *bmp)
{
uint32_t pos = 0;
uint64_t slab1_magic = 0xBADC0FFEEBADF00D;
uint64_t slab2_magic = 0xFEEDDEADDEADF00D;
uint64_t out_slab = 0;
rte_bitmap_reset(bmp);
rte_bitmap_set_slab(bmp, pos, slab1_magic);
rte_bitmap_set_slab(bmp, pos + RTE_BITMAP_SLAB_BIT_SIZE, slab2_magic);
if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
printf("Failed to get slab from bitmap.\n");
return TEST_FAILED;
}
if (slab1_magic != out_slab) {
printf("Scan operation sanity failed.\n");
return TEST_FAILED;
}
if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
printf("Failed to get slab from bitmap.\n");
return TEST_FAILED;
}
if (slab2_magic != out_slab) {
printf("Scan operation sanity failed.\n");
return TEST_FAILED;
}
/* Wrap around */
if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
printf("Failed to get slab from bitmap.\n");
return TEST_FAILED;
}
if (slab1_magic != out_slab) {
printf("Scan operation wrap around failed.\n");
return TEST_FAILED;
}
/* Scan reset check. */
__rte_bitmap_scan_init(bmp);
if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
printf("Failed to get slab from bitmap.\n");
return TEST_FAILED;
}
if (slab1_magic != out_slab) {
printf("Scan reset operation failed.\n");
return TEST_FAILED;
}
return TEST_SUCCESS;
}
static int
test_bitmap_slab_set_get(struct rte_bitmap *bmp)
{
uint32_t pos = 0;
uint64_t slab_magic = 0xBADC0FFEEBADF00D;
uint64_t out_slab = 0;
rte_bitmap_reset(bmp);
rte_bitmap_set_slab(bmp, pos, slab_magic);
if (!rte_bitmap_scan(bmp, &pos, &out_slab)) {
printf("Failed to get slab from bitmap.\n");
return TEST_FAILED;
}
if (slab_magic != out_slab) {
printf("Invalid slab in bitmap.\n");
return TEST_FAILED;
}
return TEST_SUCCESS;
}
static int
test_bitmap_set_get_clear(struct rte_bitmap *bmp)
{
uint64_t val;
int i;
rte_bitmap_reset(bmp);
for (i = 0; i < MAX_BITS; i++)
rte_bitmap_set(bmp, i);
for (i = 0; i < MAX_BITS; i++) {
if (!rte_bitmap_get(bmp, i)) {
printf("Failed to get set bit.\n");
return TEST_FAILED;
}
}
for (i = 0; i < MAX_BITS; i++)
rte_bitmap_clear(bmp, i);
for (i = 0; i < MAX_BITS; i++) {
if (rte_bitmap_get(bmp, i)) {
printf("Failed to clear set bit.\n");
return TEST_FAILED;
}
}
rte_bitmap_reset(bmp);
/* Alternate slab set test */
for (i = 0; i < MAX_BITS; i++) {
if (i % RTE_BITMAP_SLAB_BIT_SIZE)
rte_bitmap_set(bmp, i);
}
for (i = 0; i < MAX_BITS; i++) {
val = rte_bitmap_get(bmp, i);
if (((i % RTE_BITMAP_SLAB_BIT_SIZE) && !val) ||
(!(i % RTE_BITMAP_SLAB_BIT_SIZE) && val)) {
printf("Failed to get set bit.\n");
return TEST_FAILED;
}
}
return TEST_SUCCESS;
}
static int
test_bitmap_all_clear(void)
{
void *mem;
uint32_t bmp_size;
struct rte_bitmap *bmp;
bmp_size =
rte_bitmap_get_memory_footprint(MAX_BITS);
mem = rte_zmalloc("test_bmap", bmp_size, RTE_CACHE_LINE_SIZE);
if (mem == NULL) {
printf("Failed to allocate memory for bitmap\n");
return TEST_FAILED;
}
bmp = rte_bitmap_init(MAX_BITS, mem, bmp_size);
if (bmp == NULL) {
printf("Failed to init bitmap\n");
return TEST_FAILED;
}
if (test_bitmap_set_get_clear(bmp) < 0)
return TEST_FAILED;
if (test_bitmap_slab_set_get(bmp) < 0)
return TEST_FAILED;
if (test_bitmap_scan_operations(bmp) < 0)
return TEST_FAILED;
rte_bitmap_free(bmp);
rte_free(mem);
return TEST_SUCCESS;
}
static int
test_bitmap_all_set(void)
{
void *mem;
uint32_t i;
uint64_t slab;
uint32_t pos;
uint32_t bmp_size;
struct rte_bitmap *bmp;
bmp_size =
rte_bitmap_get_memory_footprint(MAX_BITS);
mem = rte_zmalloc("test_bmap", bmp_size, RTE_CACHE_LINE_SIZE);
if (mem == NULL) {
printf("Failed to allocate memory for bitmap\n");
return TEST_FAILED;
}
bmp = rte_bitmap_init_with_all_set(MAX_BITS, mem, bmp_size);
if (bmp == NULL) {
printf("Failed to init bitmap\n");
return TEST_FAILED;
}
for (i = 0; i < MAX_BITS; i++) {
pos = slab = 0;
if (!rte_bitmap_scan(bmp, &pos, &slab)) {
printf("Failed with init bitmap.\n");
return TEST_FAILED;
}
pos += (slab ? __builtin_ctzll(slab) : 0);
rte_bitmap_clear(bmp, pos);
}
if (rte_bitmap_scan(bmp, &pos, &slab)) {
printf("Too much bits set.\n");
return TEST_FAILED;
}
rte_bitmap_free(bmp);
rte_free(mem);
return TEST_SUCCESS;
}
static int
test_bitmap(void)
{
if (test_bitmap_all_clear() != TEST_SUCCESS)
return TEST_FAILED;
return test_bitmap_all_set();
}
REGISTER_TEST_COMMAND(bitmap_test, test_bitmap);