From: Mattias Rönnblom <mattias.ronnb...@ericsson.com> Extend the bitset API with atomic versions of the most basic bitset operations.
Signed-off-by: Mattias Rönnblom <mattias.ronnb...@ericsson.com> Acked-by: Tyler Retzlaff <roret...@linux.microsoft.com> --- app/test/test_bitset.c | 44 +++++++++++ lib/eal/include/rte_bitset.h | 143 +++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) diff --git a/app/test/test_bitset.c b/app/test/test_bitset.c index fd3e50f396..50b8bf0da4 100644 --- a/app/test/test_bitset.c +++ b/app/test/test_bitset.c @@ -213,6 +213,48 @@ test_flip(void) return test_flip_fun(rte_bitset_test, rte_bitset_assign, rte_bitset_flip); } +static bool +bitset_atomic_test(const uint64_t *bitset, size_t bit_num) +{ + return rte_bitset_atomic_test(bitset, bit_num, rte_memory_order_relaxed); +} + +static void +bitset_atomic_set(uint64_t *bitset, size_t bit_num) +{ + rte_bitset_atomic_set(bitset, bit_num, rte_memory_order_relaxed); +} + +static void +bitset_atomic_clear(uint64_t *bitset, size_t bit_num) +{ + rte_bitset_atomic_clear(bitset, bit_num, rte_memory_order_relaxed); +} + +static void +bitset_atomic_flip(uint64_t *bitset, size_t bit_num) +{ + rte_bitset_atomic_flip(bitset, bit_num, rte_memory_order_relaxed); +} + +static void +bitset_atomic_assign(uint64_t *bitset, size_t bit_num, bool bit_value) +{ + rte_bitset_atomic_assign(bitset, bit_num, bit_value, rte_memory_order_relaxed); +} + +static int +test_atomic_set_clear(void) +{ + return test_set_clear_fun(bitset_atomic_test, bitset_atomic_set, bitset_atomic_clear); +} + +static int +test_atomic_flip(void) +{ + return test_flip_fun(bitset_atomic_test, bitset_atomic_assign, bitset_atomic_flip); +} + static ssize_t find(const bool *ary, size_t num_bools, size_t start, size_t len, bool set) { @@ -835,6 +877,8 @@ static struct unit_test_suite bitset_tests = { .unit_test_cases = { TEST_CASE_ST(NULL, NULL, test_set_clear), TEST_CASE_ST(NULL, NULL, test_flip), + TEST_CASE_ST(NULL, NULL, test_atomic_set_clear), + TEST_CASE_ST(NULL, NULL, test_atomic_flip), TEST_CASE_ST(NULL, NULL, test_find), TEST_CASE_ST(NULL, NULL, test_foreach), TEST_CASE_ST(NULL, NULL, test_count), diff --git a/lib/eal/include/rte_bitset.h b/lib/eal/include/rte_bitset.h index b2d71aa7c6..74c643a72a 100644 --- a/lib/eal/include/rte_bitset.h +++ b/lib/eal/include/rte_bitset.h @@ -348,6 +348,149 @@ rte_bitset_flip(uint64_t *bitset, size_t bit_num) __RTE_BITSET_DELEGATE(rte_bit_flip, bitset, bit_num); } +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically test if a bit is set. + * + * Atomically test if a bit in a bitset is set with the specified + * memory ordering. + * + * @param bitset + * A pointer to the array of words making up the bitset. + * @param bit_num + * Index of the bit to test. Index 0 is the least significant bit. + * @param memory_order + * The memory order to use. + * @return + * Returns true if the bit is '1', and false if the bit is '0'. + */ +__rte_experimental +static inline bool +rte_bitset_atomic_test(const uint64_t *bitset, size_t bit_num, int memory_order) +{ + return __RTE_BITSET_DELEGATE_N(rte_bit_atomic_test, bitset, bit_num, memory_order); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically set a bit in the bitset. + * + * Set a bit in a bitset as an atomic operation, with the specified + * memory ordering. + * + * rte_bitset_atomic_set() is multi-thread safe, provided all threads + * acting in parallel on the same bitset does so through + * @c rte_bitset_atomic_*() functions. + * + * Bits are numbered from 0 to (size - 1) (inclusive). + * + * @param bitset + * A pointer to the array of words making up the bitset. + * @param bit_num + * The index of the bit to be set. + * @param memory_order + * The memory order to use. + */ +__rte_experimental +static inline void +rte_bitset_atomic_set(uint64_t *bitset, size_t bit_num, int memory_order) +{ + __RTE_BITSET_DELEGATE_N(rte_bit_atomic_set, bitset, bit_num, memory_order); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically clear a bit in the bitset. + * + * Clear a bit in a bitset as an atomic operation, with the specified + * memory ordering. + * + * rte_bitset_atomic_clear() is multi-thread safe, provided all + * threads acting in parallel on the same bitset does so through @c + * rte_bitset_atomic_*() functions. + * + * Bits are numbered from 0 to (size - 1) (inclusive). + * + * @param bitset + * A pointer to the array of words making up the bitset. + * @param bit_num + * The index of the bit to be cleared. + * @param memory_order + * The memory order to use. + */ +__rte_experimental +static inline void +rte_bitset_atomic_clear(uint64_t *bitset, size_t bit_num, int memory_order) +{ + __RTE_BITSET_DELEGATE_N(rte_bit_atomic_clear, bitset, bit_num, memory_order); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically set or clear a bit in the bitset. + * + * Assign a value to a bit in a bitset as an atomic operation, with + * the specified memory ordering. + * + * rte_bitset_atomic_assign() is multi-thread safe, provided all + * threads acting in parallel on the same bitset does so through + * @c rte_bitset_atomic_*() functions. + * + * Bits are numbered from 0 to (size - 1) (inclusive). + * + * @param bitset + * A pointer to the array of words making up the bitset. + * @param bit_num + * The index of the bit to be set or cleared. + * @param bit_value + * Control if the bit should be set or cleared. + * @param memory_order + * The memory order to use. + */ +__rte_experimental +static inline void +rte_bitset_atomic_assign(uint64_t *bitset, size_t bit_num, bool bit_value, int memory_order) +{ + __RTE_BITSET_DELEGATE_N(rte_bit_atomic_assign, bitset, bit_num, bit_value, memory_order); +} + +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice. + * + * Atomically change the value of a bit in the bitset. + * + * Flip a bit in a bitset as an atomic operation, with the specified + * memory ordering. + * + * rte_bitset_atomic_flip() is multi-thread safe, provided all threads + * acting in parallel on the same bitset does so through + * @c rte_bitset_atomic_*() functions. + * + * Bits are numbered from 0 to (size - 1) (inclusive). + * + * @param bitset + * A pointer to the array of words making up the bitset. + * @param bit_num + * The index of the bit to be flipped. + * @param memory_order + * The memory order to use. + */ +__rte_experimental +static inline void +rte_bitset_atomic_flip(uint64_t *bitset, size_t bit_num, int memory_order) +{ + __RTE_BITSET_DELEGATE_N(rte_bit_atomic_flip, bitset, bit_num, memory_order); +} + /** * @warning * @b EXPERIMENTAL: this API may change without prior notice. -- 2.46.2