util: added bit array bitmask load, store and clear
Change-Id: I7cd47184d0dfb038297c0ac04d7dfb5d31f96b6b Signed-off-by: Wojciech Malikowski <wojciech.malikowski@intel.com> Reviewed-on: https://review.gerrithub.io/432537 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Paul Luse <paul.e.luse@intel.com> Reviewed-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>
This commit is contained in:
parent
7245134ab0
commit
212eb89376
@ -173,6 +173,29 @@ uint32_t spdk_bit_array_count_set(const struct spdk_bit_array *ba);
|
|||||||
*/
|
*/
|
||||||
uint32_t spdk_bit_array_count_clear(const struct spdk_bit_array *ba);
|
uint32_t spdk_bit_array_count_clear(const struct spdk_bit_array *ba);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store bitmask from bit array.
|
||||||
|
*
|
||||||
|
* \param ba Bit array.
|
||||||
|
* \param mask Destination mask. Mask and bit array capacity must be equal.
|
||||||
|
*/
|
||||||
|
void spdk_bit_array_store_mask(const struct spdk_bit_array *ba, void *mask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load bitmask to bit array.
|
||||||
|
*
|
||||||
|
* \param ba Bit array.
|
||||||
|
* \param mask Source mask. Mask and bit array capacity must be equal.
|
||||||
|
*/
|
||||||
|
void spdk_bit_array_load_mask(struct spdk_bit_array *ba, const void *mask);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear (to 0) bit array bitmask.
|
||||||
|
*
|
||||||
|
* \param ba Bit array.
|
||||||
|
*/
|
||||||
|
void spdk_bit_array_clear_mask(struct spdk_bit_array *ba);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -311,3 +311,53 @@ spdk_bit_array_count_clear(const struct spdk_bit_array *ba)
|
|||||||
{
|
{
|
||||||
return ba->bit_count - spdk_bit_array_count_set(ba);
|
return ba->bit_count - spdk_bit_array_count_set(ba);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spdk_bit_array_store_mask(const struct spdk_bit_array *ba, void *mask)
|
||||||
|
{
|
||||||
|
uint32_t size, i;
|
||||||
|
uint32_t num_bits = spdk_bit_array_capacity(ba);
|
||||||
|
|
||||||
|
size = num_bits / CHAR_BIT;
|
||||||
|
memcpy(mask, ba->words, size);
|
||||||
|
|
||||||
|
for (i = 0; i < num_bits % CHAR_BIT; i++) {
|
||||||
|
if (spdk_bit_array_get(ba, i + size * CHAR_BIT)) {
|
||||||
|
((uint8_t *)mask)[size] |= (1U << i);
|
||||||
|
} else {
|
||||||
|
((uint8_t *)mask)[size] &= ~(1U << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spdk_bit_array_load_mask(struct spdk_bit_array *ba, const void *mask)
|
||||||
|
{
|
||||||
|
uint32_t size, i;
|
||||||
|
uint32_t num_bits = spdk_bit_array_capacity(ba);
|
||||||
|
|
||||||
|
size = num_bits / CHAR_BIT;
|
||||||
|
memcpy(ba->words, mask, size);
|
||||||
|
|
||||||
|
for (i = 0; i < num_bits % CHAR_BIT; i++) {
|
||||||
|
if (((uint8_t *)mask)[size] & (1U << i)) {
|
||||||
|
spdk_bit_array_set(ba, i + size * CHAR_BIT);
|
||||||
|
} else {
|
||||||
|
spdk_bit_array_clear(ba, i + size * CHAR_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
spdk_bit_array_clear_mask(struct spdk_bit_array *ba)
|
||||||
|
{
|
||||||
|
uint32_t size, i;
|
||||||
|
uint32_t num_bits = spdk_bit_array_capacity(ba);
|
||||||
|
|
||||||
|
size = num_bits / CHAR_BIT;
|
||||||
|
memset(ba->words, 0, size);
|
||||||
|
|
||||||
|
for (i = 0; i < num_bits % CHAR_BIT; i++) {
|
||||||
|
spdk_bit_array_clear(ba, i + size * CHAR_BIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -289,6 +289,73 @@ test_count(void)
|
|||||||
spdk_bit_array_free(&ba);
|
spdk_bit_array_free(&ba);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define TEST_MASK_SIZE 128
|
||||||
|
#define TEST_BITS_NUM (TEST_MASK_SIZE * 8 - 3)
|
||||||
|
static void
|
||||||
|
test_mask_store_load(void)
|
||||||
|
{
|
||||||
|
struct spdk_bit_array *ba;
|
||||||
|
uint8_t mask[TEST_MASK_SIZE] = { 0 };
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
ba = spdk_bit_array_create(TEST_BITS_NUM);
|
||||||
|
|
||||||
|
/* Check if stored mask is consistent with bit array mask */
|
||||||
|
spdk_bit_array_set(ba, 0);
|
||||||
|
spdk_bit_array_set(ba, TEST_BITS_NUM / 2);
|
||||||
|
spdk_bit_array_set(ba, TEST_BITS_NUM - 1);
|
||||||
|
|
||||||
|
spdk_bit_array_store_mask(ba, mask);
|
||||||
|
|
||||||
|
for (i = 0; i < TEST_BITS_NUM; i++) {
|
||||||
|
if (i == 0 || i == TEST_BITS_NUM / 2 || i == TEST_BITS_NUM - 1) {
|
||||||
|
CU_ASSERT((mask[i / 8] & (1U << (i % 8))));
|
||||||
|
} else {
|
||||||
|
CU_ASSERT(!(mask[i / 8] & (1U << (i % 8))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if loaded mask is consistent with bit array mask */
|
||||||
|
memset(mask, 0, TEST_MASK_SIZE);
|
||||||
|
mask[0] = 1;
|
||||||
|
mask[TEST_MASK_SIZE - 1] = 1U << 4;
|
||||||
|
|
||||||
|
spdk_bit_array_load_mask(ba, mask);
|
||||||
|
|
||||||
|
CU_ASSERT(spdk_bit_array_get(ba, 0));
|
||||||
|
CU_ASSERT(spdk_bit_array_get(ba, TEST_BITS_NUM - 1));
|
||||||
|
|
||||||
|
spdk_bit_array_clear(ba, 0);
|
||||||
|
spdk_bit_array_clear(ba, TEST_BITS_NUM - 1);
|
||||||
|
|
||||||
|
for (i = 0; i < TEST_BITS_NUM; i++) {
|
||||||
|
CU_ASSERT(!spdk_bit_array_get(ba, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
spdk_bit_array_free(&ba);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_mask_clear(void)
|
||||||
|
{
|
||||||
|
struct spdk_bit_array *ba;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
ba = spdk_bit_array_create(TEST_BITS_NUM);
|
||||||
|
|
||||||
|
for (i = 0; i < TEST_BITS_NUM; i++) {
|
||||||
|
spdk_bit_array_set(ba, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
spdk_bit_array_clear_mask(ba);
|
||||||
|
|
||||||
|
for (i = 0; i < TEST_BITS_NUM; i++) {
|
||||||
|
CU_ASSERT(!spdk_bit_array_get(ba, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
spdk_bit_array_free(&ba);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -311,7 +378,9 @@ main(int argc, char **argv)
|
|||||||
CU_add_test(suite, "test_find", test_find) == NULL ||
|
CU_add_test(suite, "test_find", test_find) == NULL ||
|
||||||
CU_add_test(suite, "test_resize", test_resize) == NULL ||
|
CU_add_test(suite, "test_resize", test_resize) == NULL ||
|
||||||
CU_add_test(suite, "test_errors", test_errors) == NULL ||
|
CU_add_test(suite, "test_errors", test_errors) == NULL ||
|
||||||
CU_add_test(suite, "test_count", test_count) == NULL) {
|
CU_add_test(suite, "test_count", test_count) == NULL ||
|
||||||
|
CU_add_test(suite, "test_mask_store_load", test_mask_store_load) == NULL ||
|
||||||
|
CU_add_test(suite, "test_mask_clear", test_mask_clear) == NULL) {
|
||||||
CU_cleanup_registry();
|
CU_cleanup_registry();
|
||||||
return CU_get_error();
|
return CU_get_error();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user