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

Reply via email to