mirror of https://github.com/F-Stack/f-stack.git
441 lines
9.4 KiB
C
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 */
|