On 2024-05-02 07:57, Mattias Rönnblom wrote:
Add atomic bit test/set/clear/assign/flip and
test-and-set/clear/assign/flip functions.

All atomic bit functions allow (and indeed, require) the caller to
specify a memory order.

RFC v6:
  * Have rte_bit_atomic_test() accept const-marked bitsets.

RFC v4:
  * Add atomic bit flip.
  * Mark macro-generated private functions experimental.

RFC v3:
  * Work around lack of C++ support for _Generic (Tyler Retzlaff).

RFC v2:
  o Add rte_bit_atomic_test_and_assign() (for consistency).
  o Fix bugs in rte_bit_atomic_test_and_[set|clear]().
  o Use <rte_stdatomics.h> to support MSVC.

Signed-off-by: Mattias Rönnblom <mattias.ronnb...@ericsson.com>
Acked-by: Morten Brørup <m...@smartsharesystems.com>
Acked-by: Tyler Retzlaff <roret...@linux.microsoft.com>
---
  lib/eal/include/rte_bitops.h | 428 +++++++++++++++++++++++++++++++++++
  1 file changed, 428 insertions(+)

diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h
index caec4f36bb..9cde982113 100644
--- a/lib/eal/include/rte_bitops.h
+++ b/lib/eal/include/rte_bitops.h
@@ -21,6 +21,7 @@
#include <rte_compat.h>
  #include <rte_debug.h>
+#include <rte_stdatomic.h>
#ifdef __cplusplus
  extern "C" {
@@ -399,6 +400,202 @@ extern "C" {
                 uint32_t *: __rte_bit_once_flip32,             \
                 uint64_t *: __rte_bit_once_flip64)(addr, nr)
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Test if a particular bit in a word is set with a particular memory
+ * order.
+ *
+ * Test a bit with the resulting memory load ordered as per the
+ * specified memory order.
+ *
+ * @param addr
+ *   A pointer to the word to query.
+ * @param nr
+ *   The index of the bit.
+ * @param memory_order
+ *   The memory order to use. See <rte_stdatomics.h> for details.
+ * @return
+ *   Returns true if the bit is set, and false otherwise.
+ */
+#define rte_bit_atomic_test(addr, nr, memory_order)                    \
+       _Generic((addr),                                                \
+                uint32_t *: __rte_bit_atomic_test32,                   \
+                const uint32_t *: __rte_bit_atomic_test32,             \
+                uint64_t *: __rte_bit_atomic_test64,                   \
+                const uint64_t *: __rte_bit_atomic_test64)(addr, nr,   \
+                                                           memory_order)

Should __rte_bit_atomic_test32()'s addr parameter be marked volatile, and two volatile-marked branches added to the above list? Both the C11-style GCC built-ins and the C11-proper atomic functions have addresses marked volatile. The Linux kernel and the old __sync GCC built-ins on the other hand, doesn't (although I think you still get volatile semantics). The only point of "volatile", as far as I can see, is to avoid warnings in case the user passed a volatile-marked pointer. The drawback is that *you're asking for volatile semantics*, although with the current compilers, it seems like that is what you get, regardless if you asked for it or not.

Just to be clear: even these functions would accept volatile-marked pointers, non-volatile pointers should be accepted as well (and should generally be preferred).

Isn't parallel programming in C lovely.

<snip>

Reply via email to