f-stack/dpdk/drivers/event/dlb2/pf/base/dlb2_osdep_bitmap.h

441 lines
9.4 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2016-2020 Intel Corporation
*/
#ifndef __DLB2_OSDEP_BITMAP_H
#define __DLB2_OSDEP_BITMAP_H
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <rte_bitmap.h>
#include <rte_string_fns.h>
#include <rte_malloc.h>
#include <rte_errno.h>
#include "../dlb2_main.h"
/*************************/
/*** Bitmap operations ***/
/*************************/
struct dlb2_bitmap {
struct rte_bitmap *map;
unsigned int len;
};
/**
* dlb2_bitmap_alloc() - alloc a bitmap data structure
* @bitmap: pointer to dlb2_bitmap structure pointer.
* @len: number of entries in the bitmap.
*
* This function allocates a bitmap and initializes it with length @len. All
* entries are initially zero.
*
* Return:
* Returns 0 upon success, < 0 otherwise.
*
* Errors:
* EINVAL - bitmap is NULL or len is 0.
* ENOMEM - could not allocate memory for the bitmap data structure.
*/
static inline int dlb2_bitmap_alloc(struct dlb2_bitmap **bitmap,
unsigned int len)
{
struct dlb2_bitmap *bm;
void *mem;
uint32_t alloc_size;
uint32_t nbits = (uint32_t)len;
if (bitmap == NULL || nbits == 0)
return -EINVAL;
/* Allocate DLB2 bitmap control struct */
bm = rte_malloc("DLB2_PF",
sizeof(struct dlb2_bitmap),
RTE_CACHE_LINE_SIZE);
if (bm == NULL)
return -ENOMEM;
/* Allocate bitmap memory */
alloc_size = rte_bitmap_get_memory_footprint(nbits);
mem = rte_malloc("DLB2_PF_BITMAP", alloc_size, RTE_CACHE_LINE_SIZE);
if (mem == NULL) {
rte_free(bm);
return -ENOMEM;
}
bm->map = rte_bitmap_init(len, mem, alloc_size);
if (bm->map == NULL) {
rte_free(mem);
rte_free(bm);
return -ENOMEM;
}
bm->len = len;
*bitmap = bm;
return 0;
}
/**
* dlb2_bitmap_free() - free a previously allocated bitmap data structure
* @bitmap: pointer to dlb2_bitmap structure.
*
* This function frees a bitmap that was allocated with dlb2_bitmap_alloc().
*/
static inline void dlb2_bitmap_free(struct dlb2_bitmap *bitmap)
{
if (bitmap == NULL)
return;
rte_free(bitmap->map);
rte_free(bitmap);
}
/**
* dlb2_bitmap_fill() - fill a bitmap with all 1s
* @bitmap: pointer to dlb2_bitmap structure.
*
* This function sets all bitmap values to 1.
*
* Return:
* Returns 0 upon success, < 0 otherwise.
*
* Errors:
* EINVAL - bitmap is NULL or is uninitialized.
*/
static inline int dlb2_bitmap_fill(struct dlb2_bitmap *bitmap)
{
unsigned int i;
if (bitmap == NULL || bitmap->map == NULL)
return -EINVAL;
for (i = 0; i != bitmap->len; i++)
rte_bitmap_set(bitmap->map, i);
return 0;
}
/**
* dlb2_bitmap_fill() - fill a bitmap with all 0s
* @bitmap: pointer to dlb2_bitmap structure.
*
* This function sets all bitmap values to 0.
*
* Return:
* Returns 0 upon success, < 0 otherwise.
*
* Errors:
* EINVAL - bitmap is NULL or is uninitialized.
*/
static inline int dlb2_bitmap_zero(struct dlb2_bitmap *bitmap)
{
if (bitmap == NULL || bitmap->map == NULL)
return -EINVAL;
rte_bitmap_reset(bitmap->map);
return 0;
}
/**
* dlb2_bitmap_set() - set a bitmap entry
* @bitmap: pointer to dlb2_bitmap structure.
* @bit: bit index.
*
* Return:
* Returns 0 upon success, < 0 otherwise.
*
* Errors:
* EINVAL - bitmap is NULL or is uninitialized, or bit is larger than the
* bitmap length.
*/
static inline int dlb2_bitmap_set(struct dlb2_bitmap *bitmap,
unsigned int bit)
{
if (bitmap == NULL || bitmap->map == NULL)
return -EINVAL;
if (bitmap->len <= bit)
return -EINVAL;
rte_bitmap_set(bitmap->map, bit);
return 0;
}
/**
* dlb2_bitmap_set_range() - set a range of bitmap entries
* @bitmap: pointer to dlb2_bitmap structure.
* @bit: starting bit index.
* @len: length of the range.
*
* Return:
* Returns 0 upon success, < 0 otherwise.
*
* Errors:
* EINVAL - bitmap is NULL or is uninitialized, or the range exceeds the bitmap
* length.
*/
static inline int dlb2_bitmap_set_range(struct dlb2_bitmap *bitmap,
unsigned int bit,
unsigned int len)
{
unsigned int i;
if (bitmap == NULL || bitmap->map == NULL)
return -EINVAL;
if (bitmap->len <= bit)
return -EINVAL;
for (i = 0; i != len; i++)
rte_bitmap_set(bitmap->map, bit + i);
return 0;
}
/**
* dlb2_bitmap_clear() - clear a bitmap entry
* @bitmap: pointer to dlb2_bitmap structure.
* @bit: bit index.
*
* Return:
* Returns 0 upon success, < 0 otherwise.
*
* Errors:
* EINVAL - bitmap is NULL or is uninitialized, or bit is larger than the
* bitmap length.
*/
static inline int dlb2_bitmap_clear(struct dlb2_bitmap *bitmap,
unsigned int bit)
{
if (bitmap == NULL || bitmap->map == NULL)
return -EINVAL;
if (bitmap->len <= bit)
return -EINVAL;
rte_bitmap_clear(bitmap->map, bit);
return 0;
}
/**
* dlb2_bitmap_clear_range() - clear a range of bitmap entries
* @bitmap: pointer to dlb2_bitmap structure.
* @bit: starting bit index.
* @len: length of the range.
*
* Return:
* Returns 0 upon success, < 0 otherwise.
*
* Errors:
* EINVAL - bitmap is NULL or is uninitialized, or the range exceeds the bitmap
* length.
*/
static inline int dlb2_bitmap_clear_range(struct dlb2_bitmap *bitmap,
unsigned int bit,
unsigned int len)
{
unsigned int i;
if (bitmap == NULL || bitmap->map == NULL)
return -EINVAL;
if (bitmap->len <= bit)
return -EINVAL;
for (i = 0; i != len; i++)
rte_bitmap_clear(bitmap->map, bit + i);
return 0;
}
/**
* dlb2_bitmap_find_set_bit_range() - find an range of set bits
* @bitmap: pointer to dlb2_bitmap structure.
* @len: length of the range.
*
* This function looks for a range of set bits of length @len.
*
* Return:
* Returns the base bit index upon success, < 0 otherwise.
*
* Errors:
* ENOENT - unable to find a length *len* range of set bits.
* EINVAL - bitmap is NULL or is uninitialized, or len is invalid.
*/
static inline int dlb2_bitmap_find_set_bit_range(struct dlb2_bitmap *bitmap,
unsigned int len)
{
unsigned int i, j = 0;
if (bitmap == NULL || bitmap->map == NULL || len == 0)
return -EINVAL;
if (bitmap->len < len)
return -ENOENT;
for (i = 0; i != bitmap->len; i++) {
if (rte_bitmap_get(bitmap->map, i)) {
if (++j == len)
return i - j + 1;
} else {
j = 0;
}
}
/* No set bit range of length len? */
return -ENOENT;
}
/**
* dlb2_bitmap_find_set_bit() - find an range of set bits
* @bitmap: pointer to dlb2_bitmap structure.
*
* This function looks for a single set bit.
*
* Return:
* Returns the base bit index upon success, -1 if not found, <-1 otherwise.
*
* Errors:
* EINVAL - bitmap is NULL or is uninitialized, or len is invalid.
*/
static inline int dlb2_bitmap_find_set_bit(struct dlb2_bitmap *bitmap)
{
unsigned int i;
if (bitmap == NULL)
return -EINVAL;
if (bitmap->map == NULL)
return -EINVAL;
for (i = 0; i != bitmap->len; i++) {
if (rte_bitmap_get(bitmap->map, i))
return i;
}
return -ENOENT;
}
/**
* dlb2_bitmap_count() - returns the number of set bits
* @bitmap: pointer to dlb2_bitmap structure.
*
* This function looks for a single set bit.
*
* Return:
* Returns the number of set bits upon success, <0 otherwise.
*
* Errors:
* EINVAL - bitmap is NULL or is uninitialized.
*/
static inline int dlb2_bitmap_count(struct dlb2_bitmap *bitmap)
{
int weight = 0;
unsigned int i;
if (bitmap == NULL)
return -EINVAL;
if (bitmap->map == NULL)
return -EINVAL;
for (i = 0; i != bitmap->len; i++) {
if (rte_bitmap_get(bitmap->map, i))
weight++;
}
return weight;
}
/**
* dlb2_bitmap_longest_set_range() - returns longest contiguous range of set
* bits
* @bitmap: pointer to dlb2_bitmap structure.
*
* Return:
* Returns the bitmap's longest contiguous range of set bits upon success,
* <0 otherwise.
*
* Errors:
* EINVAL - bitmap is NULL or is uninitialized.
*/
static inline int dlb2_bitmap_longest_set_range(struct dlb2_bitmap *bitmap)
{
int max_len = 0, len = 0;
unsigned int i;
if (bitmap == NULL)
return -EINVAL;
if (bitmap->map == NULL)
return -EINVAL;
for (i = 0; i != bitmap->len; i++) {
if (rte_bitmap_get(bitmap->map, i)) {
len++;
} else {
if (len > max_len)
max_len = len;
len = 0;
}
}
if (len > max_len)
max_len = len;
return max_len;
}
/**
* dlb2_bitmap_or() - store the logical 'or' of two bitmaps into a third
* @dest: pointer to dlb2_bitmap structure, which will contain the results of
* the 'or' of src1 and src2.
* @src1: pointer to dlb2_bitmap structure, will be 'or'ed with src2.
* @src2: pointer to dlb2_bitmap structure, will be 'or'ed with src1.
*
* This function 'or's two bitmaps together and stores the result in a third
* bitmap. The source and destination bitmaps can be the same.
*
* Return:
* Returns the number of set bits upon success, <0 otherwise.
*
* Errors:
* EINVAL - One of the bitmaps is NULL or is uninitialized.
*/
static inline int dlb2_bitmap_or(struct dlb2_bitmap *dest,
struct dlb2_bitmap *src1,
struct dlb2_bitmap *src2)
{
unsigned int i, min;
int numset = 0;
if (dest == NULL || dest->map == NULL ||
src1 == NULL || src1->map == NULL ||
src2 == NULL || src2->map == NULL)
return -EINVAL;
min = dest->len;
min = (min > src1->len) ? src1->len : min;
min = (min > src2->len) ? src2->len : min;
for (i = 0; i != min; i++) {
if (rte_bitmap_get(src1->map, i) ||
rte_bitmap_get(src2->map, i)) {
rte_bitmap_set(dest->map, i);
numset++;
} else {
rte_bitmap_clear(dest->map, i);
}
}
return numset;
}
#endif /* __DLB2_OSDEP_BITMAP_H */