199a11976SMattias Rönnblom /* SPDX-License-Identifier: BSD-3-Clause 299a11976SMattias Rönnblom * Copyright(c) 2023 Ericsson AB 399a11976SMattias Rönnblom */ 499a11976SMattias Rönnblom 599a11976SMattias Rönnblom #include <inttypes.h> 699a11976SMattias Rönnblom #include <stdlib.h> 799a11976SMattias Rönnblom 899a11976SMattias Rönnblom #include <rte_bitset.h> 999a11976SMattias Rönnblom #include <rte_random.h> 1099a11976SMattias Rönnblom 1199a11976SMattias Rönnblom #include "test.h" 1299a11976SMattias Rönnblom 1399a11976SMattias Rönnblom #define MAGIC UINT64_C(0xdeadbeefdeadbeef) 1499a11976SMattias Rönnblom 1599a11976SMattias Rönnblom static void 1699a11976SMattias Rönnblom rand_buf(void *buf, size_t n) 1799a11976SMattias Rönnblom { 1899a11976SMattias Rönnblom size_t i; 1999a11976SMattias Rönnblom 2099a11976SMattias Rönnblom for (i = 0; i < n; i++) 2199a11976SMattias Rönnblom ((unsigned char *)buf)[i] = rte_rand(); 2299a11976SMattias Rönnblom } 2399a11976SMattias Rönnblom 2499a11976SMattias Rönnblom static uint64_t * 2599a11976SMattias Rönnblom alloc_bitset(size_t size) 2699a11976SMattias Rönnblom { 2799a11976SMattias Rönnblom uint64_t *p; 2899a11976SMattias Rönnblom 2999a11976SMattias Rönnblom p = malloc(RTE_BITSET_SIZE(size) + 2 * sizeof(uint64_t)); 3099a11976SMattias Rönnblom if (p == NULL) 3199a11976SMattias Rönnblom rte_panic("Unable to allocate memory\n"); 3299a11976SMattias Rönnblom 3399a11976SMattias Rönnblom rand_buf(&p[0], RTE_BITSET_SIZE(size)); 3499a11976SMattias Rönnblom 3599a11976SMattias Rönnblom p[0] = MAGIC; 3699a11976SMattias Rönnblom p[RTE_BITSET_NUM_WORDS(size) + 1] = MAGIC; 3799a11976SMattias Rönnblom 3899a11976SMattias Rönnblom return p + 1; 3999a11976SMattias Rönnblom } 4099a11976SMattias Rönnblom 4199a11976SMattias Rönnblom 4299a11976SMattias Rönnblom static int 4399a11976SMattias Rönnblom free_bitset(uint64_t *bitset, size_t size) 4499a11976SMattias Rönnblom { 4599a11976SMattias Rönnblom uint64_t *p; 4699a11976SMattias Rönnblom 4799a11976SMattias Rönnblom p = bitset - 1; 4899a11976SMattias Rönnblom 4999a11976SMattias Rönnblom if (p[0] != MAGIC) 5099a11976SMattias Rönnblom return TEST_FAILED; 5199a11976SMattias Rönnblom 5299a11976SMattias Rönnblom if (p[RTE_BITSET_NUM_WORDS(size) + 1] != MAGIC) 5399a11976SMattias Rönnblom return TEST_FAILED; 5499a11976SMattias Rönnblom 5599a11976SMattias Rönnblom free(p); 5699a11976SMattias Rönnblom 5799a11976SMattias Rönnblom return TEST_SUCCESS; 5899a11976SMattias Rönnblom } 5999a11976SMattias Rönnblom 6099a11976SMattias Rönnblom static bool 6199a11976SMattias Rönnblom rand_bool(void) 6299a11976SMattias Rönnblom { 6399a11976SMattias Rönnblom return rte_rand_max(2); 6499a11976SMattias Rönnblom } 6599a11976SMattias Rönnblom 6699a11976SMattias Rönnblom static void 6799a11976SMattias Rönnblom rand_bool_ary(bool *ary, size_t len) 6899a11976SMattias Rönnblom { 6999a11976SMattias Rönnblom size_t i; 7099a11976SMattias Rönnblom 7199a11976SMattias Rönnblom for (i = 0; i < len; i++) 7299a11976SMattias Rönnblom ary[i] = rand_bool(); 7399a11976SMattias Rönnblom } 7499a11976SMattias Rönnblom 7599a11976SMattias Rönnblom static void 7699a11976SMattias Rönnblom rand_unused_bits(uint64_t *bitset, size_t size) 7799a11976SMattias Rönnblom { 7899a11976SMattias Rönnblom uint64_t bits = rte_rand() & ~__RTE_BITSET_USED_MASK(size); 7999a11976SMattias Rönnblom 8099a11976SMattias Rönnblom bitset[RTE_BITSET_NUM_WORDS(size) - 1] |= bits; 8199a11976SMattias Rönnblom } 8299a11976SMattias Rönnblom 8399a11976SMattias Rönnblom static void 8499a11976SMattias Rönnblom rand_bitset(uint64_t *bitset, size_t size) 8599a11976SMattias Rönnblom { 8699a11976SMattias Rönnblom size_t i; 8799a11976SMattias Rönnblom 8899a11976SMattias Rönnblom rte_bitset_init(bitset, size); 8999a11976SMattias Rönnblom 9099a11976SMattias Rönnblom for (i = 0; i < size; i++) 9199a11976SMattias Rönnblom rte_bitset_assign(bitset, i, rand_bool()); 9299a11976SMattias Rönnblom 9399a11976SMattias Rönnblom rand_unused_bits(bitset, size); 9499a11976SMattias Rönnblom } 9599a11976SMattias Rönnblom 9699a11976SMattias Rönnblom typedef bool test_fun(const uint64_t *bitset, size_t bit_num); 9799a11976SMattias Rönnblom typedef void set_fun(uint64_t *bitset, size_t bit_num); 9899a11976SMattias Rönnblom typedef void clear_fun(uint64_t *bitset, size_t bit_num); 9999a11976SMattias Rönnblom typedef void assign_fun(uint64_t *bitset, size_t bit_num, bool value); 10099a11976SMattias Rönnblom typedef void flip_fun(uint64_t *bitset, size_t bit_num); 10199a11976SMattias Rönnblom 10299a11976SMattias Rönnblom static int 10399a11976SMattias Rönnblom test_set_clear_size(test_fun test_fun, set_fun set_fun, clear_fun clear_fun, size_t size) 10499a11976SMattias Rönnblom { 10599a11976SMattias Rönnblom size_t i; 10699a11976SMattias Rönnblom bool reference[size]; 10799a11976SMattias Rönnblom uint64_t *bitset; 10899a11976SMattias Rönnblom 10999a11976SMattias Rönnblom rand_bool_ary(reference, size); 11099a11976SMattias Rönnblom 11199a11976SMattias Rönnblom bitset = alloc_bitset(size); 11299a11976SMattias Rönnblom 11399a11976SMattias Rönnblom TEST_ASSERT(bitset != NULL, "Failed to allocate memory"); 11499a11976SMattias Rönnblom 11599a11976SMattias Rönnblom rte_bitset_init(bitset, size); 11699a11976SMattias Rönnblom 11799a11976SMattias Rönnblom for (i = 0; i < size; i++) { 11899a11976SMattias Rönnblom if (reference[i]) 11999a11976SMattias Rönnblom set_fun(bitset, i); 12099a11976SMattias Rönnblom else 12199a11976SMattias Rönnblom clear_fun(bitset, i); 12299a11976SMattias Rönnblom } 12399a11976SMattias Rönnblom 12499a11976SMattias Rönnblom for (i = 0; i < size; i++) 12599a11976SMattias Rönnblom if (reference[i] != test_fun(bitset, i)) 12699a11976SMattias Rönnblom return TEST_FAILED; 12799a11976SMattias Rönnblom 12899a11976SMattias Rönnblom TEST_ASSERT_EQUAL(free_bitset(bitset, size), TEST_SUCCESS, 12999a11976SMattias Rönnblom "Buffer over- or underrun detected"); 13099a11976SMattias Rönnblom 13199a11976SMattias Rönnblom return TEST_SUCCESS; 13299a11976SMattias Rönnblom } 13399a11976SMattias Rönnblom 13499a11976SMattias Rönnblom #define RAND_ITERATIONS (10000) 13599a11976SMattias Rönnblom #define RAND_SET_MAX_SIZE (1000) 13699a11976SMattias Rönnblom 13799a11976SMattias Rönnblom static int 13899a11976SMattias Rönnblom test_set_clear_fun(test_fun test_fun, set_fun set_fun, clear_fun clear_fun) 13999a11976SMattias Rönnblom { 14099a11976SMattias Rönnblom size_t i; 14199a11976SMattias Rönnblom 14299a11976SMattias Rönnblom for (i = 0; i < RAND_ITERATIONS; i++) { 14399a11976SMattias Rönnblom size_t size = 1 + rte_rand_max(RAND_SET_MAX_SIZE - 1); 14499a11976SMattias Rönnblom 14599a11976SMattias Rönnblom if (test_set_clear_size(test_fun, set_fun, clear_fun, size) != TEST_SUCCESS) 14699a11976SMattias Rönnblom return TEST_FAILED; 14799a11976SMattias Rönnblom } 14899a11976SMattias Rönnblom 14999a11976SMattias Rönnblom return TEST_SUCCESS; 15099a11976SMattias Rönnblom } 15199a11976SMattias Rönnblom 15299a11976SMattias Rönnblom static int 15399a11976SMattias Rönnblom test_set_clear(void) 15499a11976SMattias Rönnblom { 15599a11976SMattias Rönnblom return test_set_clear_fun(rte_bitset_test, rte_bitset_set, rte_bitset_clear); 15699a11976SMattias Rönnblom } 15799a11976SMattias Rönnblom 15899a11976SMattias Rönnblom static int 15999a11976SMattias Rönnblom test_flip_size(test_fun test_fun, assign_fun assign_fun, flip_fun flip_fun, size_t size) 16099a11976SMattias Rönnblom { 16199a11976SMattias Rönnblom size_t i; 16299a11976SMattias Rönnblom uint64_t *bitset; 16399a11976SMattias Rönnblom 16499a11976SMattias Rönnblom bitset = alloc_bitset(size); 16599a11976SMattias Rönnblom 16699a11976SMattias Rönnblom TEST_ASSERT(bitset != NULL, "Failed to allocate memory"); 16799a11976SMattias Rönnblom 16899a11976SMattias Rönnblom rand_bitset(bitset, size); 16999a11976SMattias Rönnblom 17099a11976SMattias Rönnblom for (i = 0; i < size; i++) { 17199a11976SMattias Rönnblom RTE_BITSET_DECLARE(reference, size); 17299a11976SMattias Rönnblom 17399a11976SMattias Rönnblom rte_bitset_copy(reference, bitset, size); 17499a11976SMattias Rönnblom 17599a11976SMattias Rönnblom bool value = test_fun(bitset, i); 17699a11976SMattias Rönnblom 17799a11976SMattias Rönnblom flip_fun(bitset, i); 17899a11976SMattias Rönnblom 17999a11976SMattias Rönnblom TEST_ASSERT(test_fun(bitset, i) != value, "Bit %zd was not flipped", i); 18099a11976SMattias Rönnblom 18199a11976SMattias Rönnblom assign_fun(reference, i, !value); 18299a11976SMattias Rönnblom 18399a11976SMattias Rönnblom TEST_ASSERT(rte_bitset_equal(bitset, reference, size), 18499a11976SMattias Rönnblom "Not only the target bit %zd was flipped", i); 18599a11976SMattias Rönnblom 18699a11976SMattias Rönnblom 18799a11976SMattias Rönnblom } 18899a11976SMattias Rönnblom 18999a11976SMattias Rönnblom TEST_ASSERT_EQUAL(free_bitset(bitset, size), TEST_SUCCESS, 19099a11976SMattias Rönnblom "Buffer over- or underrun detected"); 19199a11976SMattias Rönnblom 19299a11976SMattias Rönnblom return TEST_SUCCESS; 19399a11976SMattias Rönnblom } 19499a11976SMattias Rönnblom 19599a11976SMattias Rönnblom static int 19699a11976SMattias Rönnblom test_flip_fun(test_fun test_fun, assign_fun assign_fun, flip_fun flip_fun) 19799a11976SMattias Rönnblom { 19899a11976SMattias Rönnblom size_t i; 19999a11976SMattias Rönnblom 20099a11976SMattias Rönnblom for (i = 0; i < RAND_ITERATIONS; i++) { 20199a11976SMattias Rönnblom size_t size = 1 + rte_rand_max(RAND_SET_MAX_SIZE - 1); 20299a11976SMattias Rönnblom 20399a11976SMattias Rönnblom if (test_flip_size(test_fun, assign_fun, flip_fun, size) != TEST_SUCCESS) 20499a11976SMattias Rönnblom return TEST_FAILED; 20599a11976SMattias Rönnblom } 20699a11976SMattias Rönnblom 20799a11976SMattias Rönnblom return TEST_SUCCESS; 20899a11976SMattias Rönnblom } 20999a11976SMattias Rönnblom 21099a11976SMattias Rönnblom static int 21199a11976SMattias Rönnblom test_flip(void) 21299a11976SMattias Rönnblom { 21399a11976SMattias Rönnblom return test_flip_fun(rte_bitset_test, rte_bitset_assign, rte_bitset_flip); 21499a11976SMattias Rönnblom } 21599a11976SMattias Rönnblom 216*c889c037SMattias Rönnblom static bool 217*c889c037SMattias Rönnblom bitset_atomic_test(const uint64_t *bitset, size_t bit_num) 218*c889c037SMattias Rönnblom { 219*c889c037SMattias Rönnblom return rte_bitset_atomic_test(bitset, bit_num, rte_memory_order_relaxed); 220*c889c037SMattias Rönnblom } 221*c889c037SMattias Rönnblom 222*c889c037SMattias Rönnblom static void 223*c889c037SMattias Rönnblom bitset_atomic_set(uint64_t *bitset, size_t bit_num) 224*c889c037SMattias Rönnblom { 225*c889c037SMattias Rönnblom rte_bitset_atomic_set(bitset, bit_num, rte_memory_order_relaxed); 226*c889c037SMattias Rönnblom } 227*c889c037SMattias Rönnblom 228*c889c037SMattias Rönnblom static void 229*c889c037SMattias Rönnblom bitset_atomic_clear(uint64_t *bitset, size_t bit_num) 230*c889c037SMattias Rönnblom { 231*c889c037SMattias Rönnblom rte_bitset_atomic_clear(bitset, bit_num, rte_memory_order_relaxed); 232*c889c037SMattias Rönnblom } 233*c889c037SMattias Rönnblom 234*c889c037SMattias Rönnblom static void 235*c889c037SMattias Rönnblom bitset_atomic_flip(uint64_t *bitset, size_t bit_num) 236*c889c037SMattias Rönnblom { 237*c889c037SMattias Rönnblom rte_bitset_atomic_flip(bitset, bit_num, rte_memory_order_relaxed); 238*c889c037SMattias Rönnblom } 239*c889c037SMattias Rönnblom 240*c889c037SMattias Rönnblom static void 241*c889c037SMattias Rönnblom bitset_atomic_assign(uint64_t *bitset, size_t bit_num, bool bit_value) 242*c889c037SMattias Rönnblom { 243*c889c037SMattias Rönnblom rte_bitset_atomic_assign(bitset, bit_num, bit_value, rte_memory_order_relaxed); 244*c889c037SMattias Rönnblom } 245*c889c037SMattias Rönnblom 246*c889c037SMattias Rönnblom static int 247*c889c037SMattias Rönnblom test_atomic_set_clear(void) 248*c889c037SMattias Rönnblom { 249*c889c037SMattias Rönnblom return test_set_clear_fun(bitset_atomic_test, bitset_atomic_set, bitset_atomic_clear); 250*c889c037SMattias Rönnblom } 251*c889c037SMattias Rönnblom 252*c889c037SMattias Rönnblom static int 253*c889c037SMattias Rönnblom test_atomic_flip(void) 254*c889c037SMattias Rönnblom { 255*c889c037SMattias Rönnblom return test_flip_fun(bitset_atomic_test, bitset_atomic_assign, bitset_atomic_flip); 256*c889c037SMattias Rönnblom } 257*c889c037SMattias Rönnblom 25899a11976SMattias Rönnblom static ssize_t 25999a11976SMattias Rönnblom find(const bool *ary, size_t num_bools, size_t start, size_t len, bool set) 26099a11976SMattias Rönnblom { 26199a11976SMattias Rönnblom size_t i; 26299a11976SMattias Rönnblom 26399a11976SMattias Rönnblom for (i = 0; i < len; i++) { 26499a11976SMattias Rönnblom ssize_t idx = (start + i) % num_bools; 26599a11976SMattias Rönnblom 26699a11976SMattias Rönnblom if (ary[idx] == set) 26799a11976SMattias Rönnblom return idx; 26899a11976SMattias Rönnblom } 26999a11976SMattias Rönnblom 27099a11976SMattias Rönnblom return -1; 27199a11976SMattias Rönnblom } 27299a11976SMattias Rönnblom 27399a11976SMattias Rönnblom static ssize_t 27499a11976SMattias Rönnblom find_set(const bool *ary, size_t num_bools, size_t start, size_t len) 27599a11976SMattias Rönnblom { 27699a11976SMattias Rönnblom return find(ary, num_bools, start, len, true); 27799a11976SMattias Rönnblom } 27899a11976SMattias Rönnblom 27999a11976SMattias Rönnblom static ssize_t 28099a11976SMattias Rönnblom find_clear(const bool *ary, size_t num_bools, size_t start, size_t len) 28199a11976SMattias Rönnblom { 28299a11976SMattias Rönnblom return find(ary, num_bools, start, len, false); 28399a11976SMattias Rönnblom } 28499a11976SMattias Rönnblom 28599a11976SMattias Rönnblom #define FFS_ITERATIONS (100) 28699a11976SMattias Rönnblom 28799a11976SMattias Rönnblom static int 28899a11976SMattias Rönnblom test_find_size(size_t size, bool set) 28999a11976SMattias Rönnblom { 29099a11976SMattias Rönnblom uint64_t *bitset; 29199a11976SMattias Rönnblom bool reference[size]; 29299a11976SMattias Rönnblom size_t i; 29399a11976SMattias Rönnblom 29499a11976SMattias Rönnblom bitset = alloc_bitset(size); 29599a11976SMattias Rönnblom 29699a11976SMattias Rönnblom TEST_ASSERT(bitset != NULL, "Failed to allocate memory"); 29799a11976SMattias Rönnblom 29899a11976SMattias Rönnblom rte_bitset_init(bitset, size); 29999a11976SMattias Rönnblom 30099a11976SMattias Rönnblom for (i = 0; i < size; i++) { 30199a11976SMattias Rönnblom bool bit = rand_bool(); 30299a11976SMattias Rönnblom reference[i] = bit; 30399a11976SMattias Rönnblom 30499a11976SMattias Rönnblom if (bit) 30599a11976SMattias Rönnblom rte_bitset_set(bitset, i); 30699a11976SMattias Rönnblom else /* redundant, still useful for testing */ 30799a11976SMattias Rönnblom rte_bitset_clear(bitset, i); 30899a11976SMattias Rönnblom } 30999a11976SMattias Rönnblom 31099a11976SMattias Rönnblom for (i = 0; i < FFS_ITERATIONS; i++) { 31199a11976SMattias Rönnblom size_t start_bit = rte_rand_max(size); 31299a11976SMattias Rönnblom size_t len = rte_rand_max(size + 1); 31399a11976SMattias Rönnblom bool full_range = len == size && start_bit == 0; 31499a11976SMattias Rönnblom bool wraps = start_bit + len > size; 31599a11976SMattias Rönnblom ssize_t rc; 31699a11976SMattias Rönnblom 31799a11976SMattias Rönnblom if (set) { 31899a11976SMattias Rönnblom if (full_range && rand_bool()) 31999a11976SMattias Rönnblom rc = rte_bitset_find_first_set(bitset, size); 32099a11976SMattias Rönnblom else if (wraps || rand_bool()) 32199a11976SMattias Rönnblom rc = rte_bitset_find_set_wrap(bitset, size, start_bit, len); 32299a11976SMattias Rönnblom else 32399a11976SMattias Rönnblom rc = rte_bitset_find_set(bitset, size, start_bit, len); 32499a11976SMattias Rönnblom 32599a11976SMattias Rönnblom if (rc != find_set(reference, size, start_bit, len)) 32699a11976SMattias Rönnblom return TEST_FAILED; 32799a11976SMattias Rönnblom } else { 32899a11976SMattias Rönnblom if (full_range && rand_bool()) 32999a11976SMattias Rönnblom rc = rte_bitset_find_first_clear(bitset, size); 33099a11976SMattias Rönnblom else if (wraps || rand_bool()) 33199a11976SMattias Rönnblom rc = rte_bitset_find_clear_wrap(bitset, size, start_bit, len); 33299a11976SMattias Rönnblom else 33399a11976SMattias Rönnblom rc = rte_bitset_find_clear(bitset, size, start_bit, len); 33499a11976SMattias Rönnblom 33599a11976SMattias Rönnblom if (rc != find_clear(reference, size, start_bit, len)) 33699a11976SMattias Rönnblom return TEST_FAILED; 33799a11976SMattias Rönnblom } 33899a11976SMattias Rönnblom 33999a11976SMattias Rönnblom } 34099a11976SMattias Rönnblom 34199a11976SMattias Rönnblom TEST_ASSERT_EQUAL(free_bitset(bitset, size), TEST_SUCCESS, 34299a11976SMattias Rönnblom "Buffer over- or underrun detected"); 34399a11976SMattias Rönnblom 34499a11976SMattias Rönnblom return TEST_SUCCESS; 34599a11976SMattias Rönnblom } 34699a11976SMattias Rönnblom 34799a11976SMattias Rönnblom static int 34899a11976SMattias Rönnblom test_find_set_size(size_t size) 34999a11976SMattias Rönnblom { 35099a11976SMattias Rönnblom return test_find_size(size, true); 35199a11976SMattias Rönnblom } 35299a11976SMattias Rönnblom 35399a11976SMattias Rönnblom static int 35499a11976SMattias Rönnblom test_find_clear_size(size_t size) 35599a11976SMattias Rönnblom { 35699a11976SMattias Rönnblom return test_find_size(size, false); 35799a11976SMattias Rönnblom } 35899a11976SMattias Rönnblom 35999a11976SMattias Rönnblom static int 36099a11976SMattias Rönnblom test_find(void) 36199a11976SMattias Rönnblom { 36299a11976SMattias Rönnblom size_t i; 36399a11976SMattias Rönnblom 36499a11976SMattias Rönnblom for (i = 0; i < RAND_ITERATIONS; i++) { 36599a11976SMattias Rönnblom size_t size = 2 + rte_rand_max(RAND_SET_MAX_SIZE - 2); 36699a11976SMattias Rönnblom 36799a11976SMattias Rönnblom if (test_find_set_size(size) != TEST_SUCCESS) 36899a11976SMattias Rönnblom return TEST_FAILED; 36999a11976SMattias Rönnblom 37099a11976SMattias Rönnblom if (test_find_clear_size(size) != TEST_SUCCESS) 37199a11976SMattias Rönnblom return TEST_FAILED; 37299a11976SMattias Rönnblom } 37399a11976SMattias Rönnblom 37499a11976SMattias Rönnblom return TEST_SUCCESS; 37599a11976SMattias Rönnblom } 37699a11976SMattias Rönnblom 37799a11976SMattias Rönnblom static int 37899a11976SMattias Rönnblom record_match(ssize_t match_idx, size_t size, int *calls) 37999a11976SMattias Rönnblom { 38099a11976SMattias Rönnblom if (match_idx < 0 || (size_t)match_idx >= size) 38199a11976SMattias Rönnblom return TEST_FAILED; 38299a11976SMattias Rönnblom 38399a11976SMattias Rönnblom calls[match_idx]++; 38499a11976SMattias Rönnblom 38599a11976SMattias Rönnblom return TEST_SUCCESS; 38699a11976SMattias Rönnblom } 38799a11976SMattias Rönnblom 38899a11976SMattias Rönnblom static int 38999a11976SMattias Rönnblom test_foreach_size(ssize_t size, bool may_wrap, bool set) 39099a11976SMattias Rönnblom { 39199a11976SMattias Rönnblom bool reference[size]; 39299a11976SMattias Rönnblom int calls[size]; 39399a11976SMattias Rönnblom uint64_t *bitset; 39499a11976SMattias Rönnblom ssize_t i; 39599a11976SMattias Rönnblom ssize_t start_bit; 39699a11976SMattias Rönnblom ssize_t len; 39799a11976SMattias Rönnblom bool full_range; 39899a11976SMattias Rönnblom size_t total_calls = 0; 39999a11976SMattias Rönnblom 40099a11976SMattias Rönnblom rand_bool_ary(reference, size); 40199a11976SMattias Rönnblom 40299a11976SMattias Rönnblom bitset = alloc_bitset(size); 40399a11976SMattias Rönnblom 40499a11976SMattias Rönnblom TEST_ASSERT(bitset != NULL, "Failed to allocate memory"); 40599a11976SMattias Rönnblom 40699a11976SMattias Rönnblom memset(calls, 0, sizeof(calls)); 40799a11976SMattias Rönnblom 40899a11976SMattias Rönnblom start_bit = rte_rand_max(size); 40999a11976SMattias Rönnblom len = may_wrap ? rte_rand_max(size + 1) : 41099a11976SMattias Rönnblom rte_rand_max(size - start_bit + 1); 41199a11976SMattias Rönnblom 41299a11976SMattias Rönnblom rte_bitset_init(bitset, size); 41399a11976SMattias Rönnblom 41499a11976SMattias Rönnblom /* random data in the unused bits should not matter */ 41599a11976SMattias Rönnblom rand_buf(bitset, RTE_BITSET_SIZE(size)); 41699a11976SMattias Rönnblom 41799a11976SMattias Rönnblom for (i = start_bit; i < start_bit + len; i++) { 41899a11976SMattias Rönnblom size_t idx = i % size; 41999a11976SMattias Rönnblom 42099a11976SMattias Rönnblom if (reference[idx]) 42199a11976SMattias Rönnblom rte_bitset_set(bitset, idx); 42299a11976SMattias Rönnblom else 42399a11976SMattias Rönnblom rte_bitset_clear(bitset, idx); 42499a11976SMattias Rönnblom 42599a11976SMattias Rönnblom if (rte_bitset_test(bitset, idx) != reference[idx]) 42699a11976SMattias Rönnblom return TEST_FAILED; 42799a11976SMattias Rönnblom } 42899a11976SMattias Rönnblom 42999a11976SMattias Rönnblom full_range = (len == size && start_bit == 0); 43099a11976SMattias Rönnblom 43199a11976SMattias Rönnblom /* XXX: verify iteration order as well */ 43299a11976SMattias Rönnblom if (set) { 43399a11976SMattias Rönnblom if (full_range && rand_bool()) { 43499a11976SMattias Rönnblom RTE_BITSET_FOREACH_SET(i, bitset, size) { 43599a11976SMattias Rönnblom if (record_match(i, size, calls) != TEST_SUCCESS) 43699a11976SMattias Rönnblom return TEST_FAILED; 43799a11976SMattias Rönnblom } 43899a11976SMattias Rönnblom } else if (may_wrap) { 43999a11976SMattias Rönnblom RTE_BITSET_FOREACH_SET_WRAP(i, bitset, size, start_bit, len) { 44099a11976SMattias Rönnblom if (record_match(i, size, calls) != TEST_SUCCESS) { 44199a11976SMattias Rönnblom printf("failed\n"); 44299a11976SMattias Rönnblom return TEST_FAILED; 44399a11976SMattias Rönnblom } 44499a11976SMattias Rönnblom } 44599a11976SMattias Rönnblom } else { 44699a11976SMattias Rönnblom RTE_BITSET_FOREACH_SET_RANGE(i, bitset, size, start_bit, len) { 44799a11976SMattias Rönnblom if (record_match(i, size, calls) != TEST_SUCCESS) 44899a11976SMattias Rönnblom return TEST_FAILED; 44999a11976SMattias Rönnblom } 45099a11976SMattias Rönnblom } 45199a11976SMattias Rönnblom } else { 45299a11976SMattias Rönnblom if (full_range && rand_bool()) { 45399a11976SMattias Rönnblom RTE_BITSET_FOREACH_CLEAR(i, bitset, size) 45499a11976SMattias Rönnblom if (record_match(i, size, calls) != TEST_SUCCESS) 45599a11976SMattias Rönnblom return TEST_FAILED; 45699a11976SMattias Rönnblom } else if (may_wrap) { 45799a11976SMattias Rönnblom RTE_BITSET_FOREACH_CLEAR_WRAP(i, bitset, size, start_bit, len) { 45899a11976SMattias Rönnblom if (record_match(i, size, calls) != TEST_SUCCESS) 45999a11976SMattias Rönnblom return TEST_FAILED; 46099a11976SMattias Rönnblom } 46199a11976SMattias Rönnblom } else { 46299a11976SMattias Rönnblom RTE_BITSET_FOREACH_CLEAR_RANGE(i, bitset, size, start_bit, len) 46399a11976SMattias Rönnblom if (record_match(i, size, calls) != TEST_SUCCESS) 46499a11976SMattias Rönnblom return TEST_FAILED; 46599a11976SMattias Rönnblom } 46699a11976SMattias Rönnblom } 46799a11976SMattias Rönnblom 46899a11976SMattias Rönnblom for (i = 0; i < len; i++) { 46999a11976SMattias Rönnblom size_t idx = (start_bit + i) % size; 47099a11976SMattias Rönnblom 47199a11976SMattias Rönnblom if (reference[idx] == set && calls[idx] != 1) { 47299a11976SMattias Rönnblom printf("bit %zd shouldn't have been found %d times\n", idx, calls[idx]); 47399a11976SMattias Rönnblom return TEST_FAILED; 47499a11976SMattias Rönnblom } 47599a11976SMattias Rönnblom 47699a11976SMattias Rönnblom if (reference[idx] != set && calls[idx] != 0) { 47799a11976SMattias Rönnblom puts("bar"); 47899a11976SMattias Rönnblom return TEST_FAILED; 47999a11976SMattias Rönnblom } 48099a11976SMattias Rönnblom 48199a11976SMattias Rönnblom total_calls += calls[idx]; 48299a11976SMattias Rönnblom } 48399a11976SMattias Rönnblom 48499a11976SMattias Rönnblom if (full_range) { 48599a11976SMattias Rönnblom size_t count; 48699a11976SMattias Rönnblom 48799a11976SMattias Rönnblom count = set ? rte_bitset_count_set(bitset, size) : 48899a11976SMattias Rönnblom rte_bitset_count_clear(bitset, size); 48999a11976SMattias Rönnblom 49099a11976SMattias Rönnblom if (count != total_calls) 49199a11976SMattias Rönnblom return TEST_FAILED; 49299a11976SMattias Rönnblom } 49399a11976SMattias Rönnblom 49499a11976SMattias Rönnblom TEST_ASSERT_EQUAL(free_bitset(bitset, size), TEST_SUCCESS, 49599a11976SMattias Rönnblom "Buffer over- or underrun detected"); 49699a11976SMattias Rönnblom 49799a11976SMattias Rönnblom return TEST_SUCCESS; 49899a11976SMattias Rönnblom } 49999a11976SMattias Rönnblom 50099a11976SMattias Rönnblom static int 50199a11976SMattias Rönnblom test_foreach(void) 50299a11976SMattias Rönnblom { 50399a11976SMattias Rönnblom size_t i; 50499a11976SMattias Rönnblom 50599a11976SMattias Rönnblom for (i = 0; i < RAND_ITERATIONS; i++) { 50699a11976SMattias Rönnblom size_t size = 1 + rte_rand_max(RAND_SET_MAX_SIZE - 1); 50799a11976SMattias Rönnblom 50899a11976SMattias Rönnblom if (test_foreach_size(size, false, true) != TEST_SUCCESS) 50999a11976SMattias Rönnblom return TEST_FAILED; 51099a11976SMattias Rönnblom 51199a11976SMattias Rönnblom if (test_foreach_size(size, false, false) != TEST_SUCCESS) 51299a11976SMattias Rönnblom return TEST_FAILED; 51399a11976SMattias Rönnblom 51499a11976SMattias Rönnblom if (test_foreach_size(size, true, true) != TEST_SUCCESS) 51599a11976SMattias Rönnblom return TEST_FAILED; 51699a11976SMattias Rönnblom 51799a11976SMattias Rönnblom if (test_foreach_size(size, true, false) != TEST_SUCCESS) 51899a11976SMattias Rönnblom return TEST_FAILED; 51999a11976SMattias Rönnblom } 52099a11976SMattias Rönnblom 52199a11976SMattias Rönnblom return TEST_SUCCESS; 52299a11976SMattias Rönnblom } 52399a11976SMattias Rönnblom 52499a11976SMattias Rönnblom static int 52599a11976SMattias Rönnblom test_count_size(size_t size) 52699a11976SMattias Rönnblom { 52799a11976SMattias Rönnblom uint64_t *bitset; 52899a11976SMattias Rönnblom 52999a11976SMattias Rönnblom bitset = alloc_bitset(size); 53099a11976SMattias Rönnblom 53199a11976SMattias Rönnblom TEST_ASSERT(bitset != NULL, "Failed to allocate memory"); 53299a11976SMattias Rönnblom 53399a11976SMattias Rönnblom rte_bitset_init(bitset, size); 53499a11976SMattias Rönnblom 53599a11976SMattias Rönnblom rand_unused_bits(bitset, size); 53699a11976SMattias Rönnblom 53799a11976SMattias Rönnblom if (rte_bitset_count_set(bitset, size) != 0) 53899a11976SMattias Rönnblom return TEST_FAILED; 53999a11976SMattias Rönnblom 54099a11976SMattias Rönnblom if (rte_bitset_count_clear(bitset, size) != size) 54199a11976SMattias Rönnblom return TEST_FAILED; 54299a11976SMattias Rönnblom 54399a11976SMattias Rönnblom rte_bitset_set_all(bitset, size); 54499a11976SMattias Rönnblom 54599a11976SMattias Rönnblom if (rte_bitset_count_set(bitset, size) != size) 54699a11976SMattias Rönnblom return TEST_FAILED; 54799a11976SMattias Rönnblom 54899a11976SMattias Rönnblom if (rte_bitset_count_clear(bitset, size) != 0) 54999a11976SMattias Rönnblom return TEST_FAILED; 55099a11976SMattias Rönnblom 55199a11976SMattias Rönnblom rte_bitset_clear_all(bitset, size); 55299a11976SMattias Rönnblom 55399a11976SMattias Rönnblom if (rte_bitset_count_set(bitset, size) != 0) 55499a11976SMattias Rönnblom return TEST_FAILED; 55599a11976SMattias Rönnblom 55699a11976SMattias Rönnblom if (rte_bitset_count_clear(bitset, size) != size) 55799a11976SMattias Rönnblom return TEST_FAILED; 55899a11976SMattias Rönnblom 55999a11976SMattias Rönnblom rte_bitset_set(bitset, rte_rand_max(size)); 56099a11976SMattias Rönnblom 56199a11976SMattias Rönnblom if (rte_bitset_count_set(bitset, size) != 1) 56299a11976SMattias Rönnblom return TEST_FAILED; 56399a11976SMattias Rönnblom 56499a11976SMattias Rönnblom if (rte_bitset_count_clear(bitset, size) != (size - 1)) 56599a11976SMattias Rönnblom return TEST_FAILED; 56699a11976SMattias Rönnblom 56799a11976SMattias Rönnblom rte_bitset_clear_all(bitset, size); 56899a11976SMattias Rönnblom if (rte_bitset_count_set(bitset, size) != 0) 56999a11976SMattias Rönnblom return TEST_FAILED; 57099a11976SMattias Rönnblom if (rte_bitset_count_clear(bitset, size) != size) 57199a11976SMattias Rönnblom return TEST_FAILED; 57299a11976SMattias Rönnblom 57399a11976SMattias Rönnblom rte_bitset_set_all(bitset, size); 57499a11976SMattias Rönnblom if (rte_bitset_count_set(bitset, size) != size) 57599a11976SMattias Rönnblom return TEST_FAILED; 57699a11976SMattias Rönnblom if (rte_bitset_count_clear(bitset, size) != 0) 57799a11976SMattias Rönnblom return TEST_FAILED; 57899a11976SMattias Rönnblom 57999a11976SMattias Rönnblom TEST_ASSERT_EQUAL(free_bitset(bitset, size), TEST_SUCCESS, 58099a11976SMattias Rönnblom "Buffer over- or underrun detected"); 58199a11976SMattias Rönnblom 58299a11976SMattias Rönnblom return TEST_SUCCESS; 58399a11976SMattias Rönnblom } 58499a11976SMattias Rönnblom 58599a11976SMattias Rönnblom static int 58699a11976SMattias Rönnblom test_count(void) 58799a11976SMattias Rönnblom { 58899a11976SMattias Rönnblom size_t i; 58999a11976SMattias Rönnblom 59099a11976SMattias Rönnblom if (test_count_size(128) != TEST_SUCCESS) 59199a11976SMattias Rönnblom return TEST_FAILED; 59299a11976SMattias Rönnblom if (test_count_size(1) != TEST_SUCCESS) 59399a11976SMattias Rönnblom return TEST_FAILED; 59499a11976SMattias Rönnblom if (test_count_size(63) != TEST_SUCCESS) 59599a11976SMattias Rönnblom return TEST_FAILED; 59699a11976SMattias Rönnblom if (test_count_size(64) != TEST_SUCCESS) 59799a11976SMattias Rönnblom return TEST_FAILED; 59899a11976SMattias Rönnblom if (test_count_size(65) != TEST_SUCCESS) 59999a11976SMattias Rönnblom return TEST_FAILED; 60099a11976SMattias Rönnblom 60199a11976SMattias Rönnblom for (i = 0; i < RAND_ITERATIONS; i++) { 60299a11976SMattias Rönnblom size_t size = 1 + rte_rand_max(RAND_SET_MAX_SIZE - 1); 60399a11976SMattias Rönnblom 60499a11976SMattias Rönnblom if (test_count_size(size) != TEST_SUCCESS) 60599a11976SMattias Rönnblom return TEST_FAILED; 60699a11976SMattias Rönnblom } 60799a11976SMattias Rönnblom 60899a11976SMattias Rönnblom return TEST_SUCCESS; 60999a11976SMattias Rönnblom } 61099a11976SMattias Rönnblom 61199a11976SMattias Rönnblom #define GEN_DECLARE(size) \ 61299a11976SMattias Rönnblom { \ 61399a11976SMattias Rönnblom RTE_BITSET_DECLARE(bitset, size); \ 61499a11976SMattias Rönnblom size_t idx = rte_rand_max(size); \ 61599a11976SMattias Rönnblom rte_bitset_init(bitset, size); \ 61699a11976SMattias Rönnblom rte_bitset_set(bitset, idx); \ 61799a11976SMattias Rönnblom if (!rte_bitset_test(bitset, idx)) \ 61899a11976SMattias Rönnblom return TEST_FAILED; \ 61999a11976SMattias Rönnblom if (rte_bitset_count_set(bitset, size) != 1) \ 62099a11976SMattias Rönnblom return TEST_FAILED; \ 62199a11976SMattias Rönnblom return TEST_SUCCESS; \ 62299a11976SMattias Rönnblom } 62399a11976SMattias Rönnblom 62499a11976SMattias Rönnblom static int 62599a11976SMattias Rönnblom test_define(void) 62699a11976SMattias Rönnblom { 62799a11976SMattias Rönnblom GEN_DECLARE(1); 62899a11976SMattias Rönnblom GEN_DECLARE(64); 62999a11976SMattias Rönnblom GEN_DECLARE(65); 63099a11976SMattias Rönnblom GEN_DECLARE(4097); 63199a11976SMattias Rönnblom } 63299a11976SMattias Rönnblom 63399a11976SMattias Rönnblom typedef void bitset_op(uint64_t *dst, const uint64_t *a, const uint64_t *b, size_t bit_num); 63499a11976SMattias Rönnblom typedef bool bool_op(bool a, bool b); 63599a11976SMattias Rönnblom 63699a11976SMattias Rönnblom static int 63799a11976SMattias Rönnblom test_logic_op(bitset_op bitset_op, bool_op bool_op) 63899a11976SMattias Rönnblom { 63999a11976SMattias Rönnblom const size_t size = 1 + rte_rand_max(200); 64099a11976SMattias Rönnblom RTE_BITSET_DECLARE(bitset_a, size); 64199a11976SMattias Rönnblom RTE_BITSET_DECLARE(bitset_b, size); 64299a11976SMattias Rönnblom RTE_BITSET_DECLARE(bitset_d, size); 64399a11976SMattias Rönnblom 64499a11976SMattias Rönnblom bool ary_a[size]; 64599a11976SMattias Rönnblom bool ary_b[size]; 64699a11976SMattias Rönnblom bool ary_d[size]; 64799a11976SMattias Rönnblom 64899a11976SMattias Rönnblom rand_bool_ary(ary_a, size); 64999a11976SMattias Rönnblom rand_bool_ary(ary_b, size); 65099a11976SMattias Rönnblom 65199a11976SMattias Rönnblom size_t i; 65299a11976SMattias Rönnblom for (i = 0; i < size; i++) { 65399a11976SMattias Rönnblom rte_bitset_assign(bitset_a, i, ary_a[i]); 65499a11976SMattias Rönnblom rte_bitset_assign(bitset_b, i, ary_b[i]); 65599a11976SMattias Rönnblom ary_d[i] = bool_op(ary_a[i], ary_b[i]); 65699a11976SMattias Rönnblom } 65799a11976SMattias Rönnblom 65899a11976SMattias Rönnblom bitset_op(bitset_d, bitset_a, bitset_b, size); 65999a11976SMattias Rönnblom 66099a11976SMattias Rönnblom for (i = 0; i < size; i++) 66199a11976SMattias Rönnblom TEST_ASSERT_EQUAL(rte_bitset_test(bitset_d, i), ary_d[i], 66299a11976SMattias Rönnblom "Unexpected value of bit %zd", i); 66399a11976SMattias Rönnblom 66499a11976SMattias Rönnblom return TEST_SUCCESS; 66599a11976SMattias Rönnblom } 66699a11976SMattias Rönnblom 66799a11976SMattias Rönnblom static bool 66899a11976SMattias Rönnblom bool_or(bool a, bool b) 66999a11976SMattias Rönnblom { 67099a11976SMattias Rönnblom return a || b; 67199a11976SMattias Rönnblom } 67299a11976SMattias Rönnblom 67399a11976SMattias Rönnblom static int 67499a11976SMattias Rönnblom test_or(void) 67599a11976SMattias Rönnblom { 67699a11976SMattias Rönnblom return test_logic_op(rte_bitset_or, bool_or); 67799a11976SMattias Rönnblom } 67899a11976SMattias Rönnblom 67999a11976SMattias Rönnblom static bool 68099a11976SMattias Rönnblom bool_and(bool a, bool b) 68199a11976SMattias Rönnblom { 68299a11976SMattias Rönnblom return a && b; 68399a11976SMattias Rönnblom } 68499a11976SMattias Rönnblom 68599a11976SMattias Rönnblom static int 68699a11976SMattias Rönnblom test_and(void) 68799a11976SMattias Rönnblom { 68899a11976SMattias Rönnblom return test_logic_op(rte_bitset_and, bool_and); 68999a11976SMattias Rönnblom } 69099a11976SMattias Rönnblom 69199a11976SMattias Rönnblom static bool 69299a11976SMattias Rönnblom bool_xor(bool a, bool b) 69399a11976SMattias Rönnblom { 69499a11976SMattias Rönnblom return a != b; 69599a11976SMattias Rönnblom } 69699a11976SMattias Rönnblom 69799a11976SMattias Rönnblom static int 69899a11976SMattias Rönnblom test_xor(void) 69999a11976SMattias Rönnblom { 70099a11976SMattias Rönnblom return test_logic_op(rte_bitset_xor, bool_xor); 70199a11976SMattias Rönnblom } 70299a11976SMattias Rönnblom 70399a11976SMattias Rönnblom static int 70499a11976SMattias Rönnblom test_complement(void) 70599a11976SMattias Rönnblom { 70699a11976SMattias Rönnblom int i; 70799a11976SMattias Rönnblom 70899a11976SMattias Rönnblom for (i = 0; i < RAND_ITERATIONS; i++) { 70999a11976SMattias Rönnblom const size_t size = 1 + rte_rand_max(RAND_SET_MAX_SIZE - 1); 71099a11976SMattias Rönnblom 71199a11976SMattias Rönnblom RTE_BITSET_DECLARE(src, size); 71299a11976SMattias Rönnblom 71399a11976SMattias Rönnblom rand_bitset(src, size); 71499a11976SMattias Rönnblom 71599a11976SMattias Rönnblom bool bit_idx = rte_rand_max(size); 71699a11976SMattias Rönnblom bool bit_value = rte_bitset_test(src, bit_idx); 71799a11976SMattias Rönnblom 71899a11976SMattias Rönnblom RTE_BITSET_DECLARE(dst, size); 71999a11976SMattias Rönnblom 72099a11976SMattias Rönnblom rte_bitset_complement(dst, src, size); 72199a11976SMattias Rönnblom 72299a11976SMattias Rönnblom TEST_ASSERT(bit_value != rte_bitset_test(dst, bit_idx), 72399a11976SMattias Rönnblom "Bit %d was not flipped", bit_idx); 72499a11976SMattias Rönnblom } 72599a11976SMattias Rönnblom 72699a11976SMattias Rönnblom return TEST_SUCCESS; 72799a11976SMattias Rönnblom } 72899a11976SMattias Rönnblom 72999a11976SMattias Rönnblom static int 73099a11976SMattias Rönnblom test_shift(bool right) 73199a11976SMattias Rönnblom { 73299a11976SMattias Rönnblom int i; 73399a11976SMattias Rönnblom 73499a11976SMattias Rönnblom const char *direction = right ? "right" : "left"; 73599a11976SMattias Rönnblom 73699a11976SMattias Rönnblom for (i = 0; i < 10000; i++) { 73799a11976SMattias Rönnblom const int size = 1 + (int)rte_rand_max(500); 73899a11976SMattias Rönnblom const int shift_count = (int)rte_rand_max(1.5 * size); 73999a11976SMattias Rönnblom int src_idx; 74099a11976SMattias Rönnblom 74199a11976SMattias Rönnblom RTE_BITSET_DECLARE(src, size); 74299a11976SMattias Rönnblom RTE_BITSET_DECLARE(reference, size); 74399a11976SMattias Rönnblom 74499a11976SMattias Rönnblom rte_bitset_init(src, size); 74599a11976SMattias Rönnblom rte_bitset_init(reference, size); 74699a11976SMattias Rönnblom 74799a11976SMattias Rönnblom rand_unused_bits(src, size); 74899a11976SMattias Rönnblom rand_unused_bits(reference, size); 74999a11976SMattias Rönnblom 75099a11976SMattias Rönnblom for (src_idx = 0; src_idx < size; src_idx++) { 75199a11976SMattias Rönnblom bool value = rand_bool(); 75299a11976SMattias Rönnblom 75399a11976SMattias Rönnblom rte_bitset_assign(src, src_idx, value); 75499a11976SMattias Rönnblom 75599a11976SMattias Rönnblom int dst_idx = right ? src_idx - shift_count : src_idx + shift_count; 75699a11976SMattias Rönnblom 75799a11976SMattias Rönnblom if (dst_idx >= 0 && dst_idx < size) 75899a11976SMattias Rönnblom rte_bitset_assign(reference, dst_idx, value); 75999a11976SMattias Rönnblom } 76099a11976SMattias Rönnblom 76199a11976SMattias Rönnblom uint64_t *dst = alloc_bitset(size); 76299a11976SMattias Rönnblom 76399a11976SMattias Rönnblom if (right) 76499a11976SMattias Rönnblom rte_bitset_shift_right(dst, src, size, shift_count); 76599a11976SMattias Rönnblom else 76699a11976SMattias Rönnblom rte_bitset_shift_left(dst, src, size, shift_count); 76799a11976SMattias Rönnblom 76899a11976SMattias Rönnblom TEST_ASSERT(rte_bitset_equal(dst, reference, size), 76999a11976SMattias Rönnblom "Unexpected result from shifting bitset of size %d bits %d bits %s", 77099a11976SMattias Rönnblom size, shift_count, direction); 77199a11976SMattias Rönnblom 77299a11976SMattias Rönnblom TEST_ASSERT_EQUAL(free_bitset(dst, size), TEST_SUCCESS, 77399a11976SMattias Rönnblom "Shift %s operation overwrote buffer", direction); 77499a11976SMattias Rönnblom } 77599a11976SMattias Rönnblom 77699a11976SMattias Rönnblom return TEST_SUCCESS; 77799a11976SMattias Rönnblom } 77899a11976SMattias Rönnblom 77999a11976SMattias Rönnblom static int 78099a11976SMattias Rönnblom test_shift_right(void) 78199a11976SMattias Rönnblom { 78299a11976SMattias Rönnblom return test_shift(true); 78399a11976SMattias Rönnblom } 78499a11976SMattias Rönnblom 78599a11976SMattias Rönnblom static int 78699a11976SMattias Rönnblom test_shift_left(void) 78799a11976SMattias Rönnblom { 78899a11976SMattias Rönnblom return test_shift(false); 78999a11976SMattias Rönnblom } 79099a11976SMattias Rönnblom 79199a11976SMattias Rönnblom static int 79299a11976SMattias Rönnblom test_equal(void) 79399a11976SMattias Rönnblom { 79499a11976SMattias Rönnblom const size_t size = 100; 79599a11976SMattias Rönnblom RTE_BITSET_DECLARE(bitset_a, size); 79699a11976SMattias Rönnblom RTE_BITSET_DECLARE(bitset_b, size); 79799a11976SMattias Rönnblom 79899a11976SMattias Rönnblom rand_buf(bitset_a, RTE_BITSET_SIZE(size)); 79999a11976SMattias Rönnblom rand_buf(bitset_b, RTE_BITSET_SIZE(size)); 80099a11976SMattias Rönnblom 80199a11976SMattias Rönnblom rte_bitset_init(bitset_a, size); 80299a11976SMattias Rönnblom rte_bitset_init(bitset_b, size); 80399a11976SMattias Rönnblom 80499a11976SMattias Rönnblom rte_bitset_set(bitset_a, 9); 80599a11976SMattias Rönnblom rte_bitset_set(bitset_b, 9); 80699a11976SMattias Rönnblom rte_bitset_set(bitset_a, 90); 80799a11976SMattias Rönnblom rte_bitset_set(bitset_b, 90); 80899a11976SMattias Rönnblom 80999a11976SMattias Rönnblom if (!rte_bitset_equal(bitset_a, bitset_b, size)) 81099a11976SMattias Rönnblom return TEST_FAILED; 81199a11976SMattias Rönnblom 81299a11976SMattias Rönnblom /* set unused bit, which should be ignored */ 81399a11976SMattias Rönnblom rte_bitset_set(&bitset_a[1], 60); 81499a11976SMattias Rönnblom 81599a11976SMattias Rönnblom if (!rte_bitset_equal(bitset_a, bitset_b, size)) 81699a11976SMattias Rönnblom return TEST_FAILED; 81799a11976SMattias Rönnblom 81899a11976SMattias Rönnblom return TEST_SUCCESS; 81999a11976SMattias Rönnblom } 82099a11976SMattias Rönnblom 82199a11976SMattias Rönnblom static int 82299a11976SMattias Rönnblom test_copy(void) 82399a11976SMattias Rönnblom { 82499a11976SMattias Rönnblom const size_t size = 100; 82599a11976SMattias Rönnblom RTE_BITSET_DECLARE(bitset_a, size); 82699a11976SMattias Rönnblom RTE_BITSET_DECLARE(bitset_b, size); 82799a11976SMattias Rönnblom 82899a11976SMattias Rönnblom rand_buf(bitset_a, RTE_BITSET_SIZE(size)); 82999a11976SMattias Rönnblom rand_buf(bitset_b, RTE_BITSET_SIZE(size)); 83099a11976SMattias Rönnblom 83199a11976SMattias Rönnblom rte_bitset_copy(bitset_a, bitset_b, size); 83299a11976SMattias Rönnblom 83399a11976SMattias Rönnblom if (!rte_bitset_equal(bitset_a, bitset_b, size)) 83499a11976SMattias Rönnblom return TEST_FAILED; 83599a11976SMattias Rönnblom 83699a11976SMattias Rönnblom return TEST_SUCCESS; 83799a11976SMattias Rönnblom } 83899a11976SMattias Rönnblom 83999a11976SMattias Rönnblom static int 84099a11976SMattias Rönnblom test_to_str(void) 84199a11976SMattias Rönnblom { 84299a11976SMattias Rönnblom char buf[1024]; 84399a11976SMattias Rönnblom RTE_BITSET_DECLARE(bitset, 128); 84499a11976SMattias Rönnblom 84599a11976SMattias Rönnblom rte_bitset_init(bitset, 128); 84699a11976SMattias Rönnblom rte_bitset_set(bitset, 1); 84799a11976SMattias Rönnblom 84899a11976SMattias Rönnblom if (rte_bitset_to_str(bitset, 2, buf, 3) != 3) 84999a11976SMattias Rönnblom return TEST_FAILED; 85099a11976SMattias Rönnblom if (strcmp(buf, "10") != 0) 85199a11976SMattias Rönnblom return TEST_FAILED; 85299a11976SMattias Rönnblom 85399a11976SMattias Rönnblom rte_bitset_set(bitset, 0); 85499a11976SMattias Rönnblom 85599a11976SMattias Rönnblom if (rte_bitset_to_str(bitset, 1, buf, sizeof(buf)) != 2) 85699a11976SMattias Rönnblom return TEST_FAILED; 85799a11976SMattias Rönnblom if (strcmp(buf, "1") != 0) 85899a11976SMattias Rönnblom return TEST_FAILED; 85999a11976SMattias Rönnblom 86099a11976SMattias Rönnblom rte_bitset_init(bitset, 99); 86199a11976SMattias Rönnblom rte_bitset_set(bitset, 98); 86299a11976SMattias Rönnblom 86399a11976SMattias Rönnblom if (rte_bitset_to_str(bitset, 99, buf, sizeof(buf)) != 100) 86499a11976SMattias Rönnblom return TEST_FAILED; 86599a11976SMattias Rönnblom 86699a11976SMattias Rönnblom if (buf[0] != '1' || strchr(&buf[1], '1') != NULL) 86799a11976SMattias Rönnblom return TEST_FAILED; 86899a11976SMattias Rönnblom 86999a11976SMattias Rönnblom if (rte_bitset_to_str(bitset, 128, buf, 64) != -EINVAL) 87099a11976SMattias Rönnblom return TEST_FAILED; 87199a11976SMattias Rönnblom 87299a11976SMattias Rönnblom return TEST_SUCCESS; 87399a11976SMattias Rönnblom } 87499a11976SMattias Rönnblom 87599a11976SMattias Rönnblom static struct unit_test_suite bitset_tests = { 87699a11976SMattias Rönnblom .suite_name = "bitset test suite", 87799a11976SMattias Rönnblom .unit_test_cases = { 87899a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_set_clear), 87999a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_flip), 880*c889c037SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_atomic_set_clear), 881*c889c037SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_atomic_flip), 88299a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_find), 88399a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_foreach), 88499a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_count), 88599a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_define), 88699a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_or), 88799a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_and), 88899a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_xor), 88999a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_complement), 89099a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_shift_right), 89199a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_shift_left), 89299a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_equal), 89399a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_copy), 89499a11976SMattias Rönnblom TEST_CASE_ST(NULL, NULL, test_to_str), 89599a11976SMattias Rönnblom TEST_CASES_END() 89699a11976SMattias Rönnblom } 89799a11976SMattias Rönnblom }; 89899a11976SMattias Rönnblom 89999a11976SMattias Rönnblom static int 90099a11976SMattias Rönnblom test_bitset(void) 90199a11976SMattias Rönnblom { 90299a11976SMattias Rönnblom return unit_test_suite_runner(&bitset_tests); 90399a11976SMattias Rönnblom } 90499a11976SMattias Rönnblom 90599a11976SMattias Rönnblom REGISTER_FAST_TEST(bitset_autotest, true, true, test_bitset); 906