Hi Mattias, I have a comment about the _Generic. What if the user gives uint8_t * or uint16_t * as the address. One improvement is that we could add a default branch in _Generic to throw a compiler error or assert false. Another question is what if nr >= sizeof(type) ? What if you do, for example, (uint32_t)1 << 35? Maybe we could add an assert in the implementation?
Regards, Heng -----Original Message----- From: Mattias Rönnblom <mattias.ronnb...@ericsson.com> Sent: Saturday, March 2, 2024 2:53 PM To: dev@dpdk.org Cc: hof...@lysator.liu.se; Heng Wang <heng.w...@ericsson.com>; Mattias Rönnblom <mattias.ronnb...@ericsson.com> Subject: [RFC 2/7] eal: add generic bit manipulation macros Add bit-level test/set/clear/assign macros operating on both 32-bit and 64-bit words by means of C11 generic selection. Signed-off-by: Mattias Rönnblom <mattias.ronnb...@ericsson.com> --- lib/eal/include/rte_bitops.h | 81 ++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/lib/eal/include/rte_bitops.h b/lib/eal/include/rte_bitops.h index 9a368724d5..afd0f11033 100644 --- a/lib/eal/include/rte_bitops.h +++ b/lib/eal/include/rte_bitops.h @@ -107,6 +107,87 @@ extern "C" { #define RTE_FIELD_GET64(mask, reg) \ ((typeof(mask))(((reg) & (mask)) >> rte_ctz64(mask))) +/** + * Test bit in word. + * + * Generic selection macro to test the value of a bit in a 32-bit or + * 64-bit word. The type of operation depends on the type of the @c + * addr parameter. + * + * This macro does not give any guarantees in regards to memory + * ordering or atomicity. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + */ +#define rte_bit_test(addr, nr) \ + _Generic((addr), \ + uint32_t *: rte_bit_test32, \ + uint64_t *: rte_bit_test64)(addr, nr) + +/** + * Set bit in word. + * + * Generic selection macro to set a bit in a 32-bit or 64-bit + * word. The type of operation depends on the type of the @c addr + * parameter. + * + * This macro does not give any guarantees in regards to memory + * ordering or atomicity. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + */ +#define rte_bit_set(addr, nr) \ + _Generic((addr), \ + uint32_t *: rte_bit_set32, \ + uint64_t *: rte_bit_set64)(addr, nr) + +/** + * Clear bit in word. + * + * Generic selection macro to clear a bit in a 32-bit or 64-bit + * word. The type of operation depends on the type of the @c addr + * parameter. + * + * This macro does not give any guarantees in regards to memory + * ordering or atomicity. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + */ +#define rte_bit_clear(addr, nr) \ + _Generic((addr), \ + uint32_t *: rte_bit_clear32, \ + uint64_t *: rte_bit_clear64)(addr, nr) + +/** + * Assign a value to a bit in word. + * + * Generic selection macro to assign a value to a bit in a 32-bit or +64-bit + * word. The type of operation depends on the type of the @c addr parameter. + * + * This macro does not give any guarantees in regards to memory + * ordering or atomicity. + * + * @param addr + * A pointer to the word to modify. + * @param nr + * The index of the bit. + * @param value + * The new value of the bit - true for '1', or false for '0'. + */ +#define rte_bit_assign(addr, nr, value) \ + _Generic((addr), \ + uint32_t *: rte_bit_assign32, \ + uint64_t *: rte_bit_assign64)(addr, nr, value) + /** * Test if a particular bit in a 32-bit word is set. * -- 2.34.1