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:
Wojciech Malikowski 2018-11-08 03:41:47 -05:00 committed by Jim Harris
parent 7245134ab0
commit 212eb89376
3 changed files with 143 additions and 1 deletions

View File

@ -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);
/**
* 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
}
#endif

View File

@ -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);
}
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);
}
}

View File

@ -289,6 +289,73 @@ test_count(void)
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
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_resize", test_resize) == 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();
return CU_get_error();
}