xref: /dpdk/lib/eal/include/rte_stdatomic.h (revision 719834a6849e1daf4a70ff7742bbcc3ae7e25607)
15c381a35STyler Retzlaff /* SPDX-License-Identifier: BSD-3-Clause
25c381a35STyler Retzlaff  * Copyright(c) 2023 Microsoft Corporation
35c381a35STyler Retzlaff  */
45c381a35STyler Retzlaff 
55c381a35STyler Retzlaff #ifndef RTE_STDATOMIC_H
65c381a35STyler Retzlaff #define RTE_STDATOMIC_H
75c381a35STyler Retzlaff 
85c381a35STyler Retzlaff #include <assert.h>
95c381a35STyler Retzlaff 
105c381a35STyler Retzlaff #ifdef RTE_ENABLE_STDATOMIC
11*1025bd1cSTyler Retzlaff #ifndef _MSC_VER
125c381a35STyler Retzlaff #ifdef __STDC_NO_ATOMICS__
135c381a35STyler Retzlaff #error enable_stdatomic=true but atomics not supported by toolchain
145c381a35STyler Retzlaff #endif
15*1025bd1cSTyler Retzlaff #endif
165c381a35STyler Retzlaff 
175c381a35STyler Retzlaff #include <stdatomic.h>
185c381a35STyler Retzlaff 
195c381a35STyler Retzlaff /* RTE_ATOMIC(type) is provided for use as a type specifier
205c381a35STyler Retzlaff  * permitting designation of an rte atomic type.
215c381a35STyler Retzlaff  */
225c381a35STyler Retzlaff #define RTE_ATOMIC(type) _Atomic(type)
235c381a35STyler Retzlaff 
245c381a35STyler Retzlaff /* __rte_atomic is provided for type qualification permitting
255c381a35STyler Retzlaff  * designation of an rte atomic qualified type-name.
265c381a35STyler Retzlaff  */
275c381a35STyler Retzlaff #define __rte_atomic _Atomic
285c381a35STyler Retzlaff 
295c381a35STyler Retzlaff /* The memory order is an enumerated type in C11. */
305c381a35STyler Retzlaff typedef memory_order rte_memory_order;
315c381a35STyler Retzlaff 
325c381a35STyler Retzlaff #define rte_memory_order_relaxed memory_order_relaxed
335c381a35STyler Retzlaff #ifdef __ATOMIC_RELAXED
345c381a35STyler Retzlaff static_assert(rte_memory_order_relaxed == __ATOMIC_RELAXED,
355c381a35STyler Retzlaff 	"rte_memory_order_relaxed == __ATOMIC_RELAXED");
365c381a35STyler Retzlaff #endif
375c381a35STyler Retzlaff 
385c381a35STyler Retzlaff #define rte_memory_order_consume memory_order_consume
395c381a35STyler Retzlaff #ifdef __ATOMIC_CONSUME
405c381a35STyler Retzlaff static_assert(rte_memory_order_consume == __ATOMIC_CONSUME,
415c381a35STyler Retzlaff 	"rte_memory_order_consume == __ATOMIC_CONSUME");
425c381a35STyler Retzlaff #endif
435c381a35STyler Retzlaff 
445c381a35STyler Retzlaff #define rte_memory_order_acquire memory_order_acquire
455c381a35STyler Retzlaff #ifdef __ATOMIC_ACQUIRE
465c381a35STyler Retzlaff static_assert(rte_memory_order_acquire == __ATOMIC_ACQUIRE,
475c381a35STyler Retzlaff 	"rte_memory_order_acquire == __ATOMIC_ACQUIRE");
485c381a35STyler Retzlaff #endif
495c381a35STyler Retzlaff 
505c381a35STyler Retzlaff #define rte_memory_order_release memory_order_release
515c381a35STyler Retzlaff #ifdef __ATOMIC_RELEASE
525c381a35STyler Retzlaff static_assert(rte_memory_order_release == __ATOMIC_RELEASE,
535c381a35STyler Retzlaff 	"rte_memory_order_release == __ATOMIC_RELEASE");
545c381a35STyler Retzlaff #endif
555c381a35STyler Retzlaff 
565c381a35STyler Retzlaff #define rte_memory_order_acq_rel memory_order_acq_rel
575c381a35STyler Retzlaff #ifdef __ATOMIC_ACQ_REL
585c381a35STyler Retzlaff static_assert(rte_memory_order_acq_rel == __ATOMIC_ACQ_REL,
595c381a35STyler Retzlaff 	"rte_memory_order_acq_rel == __ATOMIC_ACQ_REL");
605c381a35STyler Retzlaff #endif
615c381a35STyler Retzlaff 
625c381a35STyler Retzlaff #define rte_memory_order_seq_cst memory_order_seq_cst
635c381a35STyler Retzlaff #ifdef __ATOMIC_SEQ_CST
645c381a35STyler Retzlaff static_assert(rte_memory_order_seq_cst == __ATOMIC_SEQ_CST,
655c381a35STyler Retzlaff 	"rte_memory_order_seq_cst == __ATOMIC_SEQ_CST");
665c381a35STyler Retzlaff #endif
675c381a35STyler Retzlaff 
685c381a35STyler Retzlaff #define rte_atomic_load_explicit(ptr, memorder) \
695c381a35STyler Retzlaff 	atomic_load_explicit(ptr, memorder)
705c381a35STyler Retzlaff 
715c381a35STyler Retzlaff #define rte_atomic_store_explicit(ptr, val, memorder) \
725c381a35STyler Retzlaff 	atomic_store_explicit(ptr, val, memorder)
735c381a35STyler Retzlaff 
745c381a35STyler Retzlaff #define rte_atomic_exchange_explicit(ptr, val, memorder) \
755c381a35STyler Retzlaff 	atomic_exchange_explicit(ptr, val, memorder)
765c381a35STyler Retzlaff 
775c381a35STyler Retzlaff #define rte_atomic_compare_exchange_strong_explicit(ptr, expected, desired, \
785c381a35STyler Retzlaff 		succ_memorder, fail_memorder) \
795c381a35STyler Retzlaff 	atomic_compare_exchange_strong_explicit(ptr, expected, desired, \
805c381a35STyler Retzlaff 		succ_memorder, fail_memorder)
815c381a35STyler Retzlaff 
825c381a35STyler Retzlaff #define rte_atomic_compare_exchange_weak_explicit(ptr, expected, desired, \
835c381a35STyler Retzlaff 		succ_memorder, fail_memorder) \
845c381a35STyler Retzlaff 	atomic_compare_exchange_weak_explicit(ptr, expected, desired, \
855c381a35STyler Retzlaff 		succ_memorder, fail_memorder)
865c381a35STyler Retzlaff 
875c381a35STyler Retzlaff #define rte_atomic_fetch_add_explicit(ptr, val, memorder) \
885c381a35STyler Retzlaff 	atomic_fetch_add_explicit(ptr, val, memorder)
895c381a35STyler Retzlaff 
905c381a35STyler Retzlaff #define rte_atomic_fetch_sub_explicit(ptr, val, memorder) \
915c381a35STyler Retzlaff 	atomic_fetch_sub_explicit(ptr, val, memorder)
925c381a35STyler Retzlaff 
935c381a35STyler Retzlaff #define rte_atomic_fetch_and_explicit(ptr, val, memorder) \
945c381a35STyler Retzlaff 	atomic_fetch_and_explicit(ptr, val, memorder)
955c381a35STyler Retzlaff 
965c381a35STyler Retzlaff #define rte_atomic_fetch_xor_explicit(ptr, val, memorder) \
975c381a35STyler Retzlaff 	atomic_fetch_xor_explicit(ptr, val, memorder)
985c381a35STyler Retzlaff 
995c381a35STyler Retzlaff #define rte_atomic_fetch_or_explicit(ptr, val, memorder) \
1005c381a35STyler Retzlaff 	atomic_fetch_or_explicit(ptr, val, memorder)
1015c381a35STyler Retzlaff 
1025c381a35STyler Retzlaff #define rte_atomic_fetch_nand_explicit(ptr, val, memorder) \
1035c381a35STyler Retzlaff 	atomic_fetch_nand_explicit(ptr, val, memorder)
1045c381a35STyler Retzlaff 
1055c381a35STyler Retzlaff #define rte_atomic_flag_test_and_set_explicit(ptr, memorder) \
1065c381a35STyler Retzlaff 	atomic_flag_test_and_set_explicit(ptr, memorder)
1075c381a35STyler Retzlaff 
1085c381a35STyler Retzlaff #define rte_atomic_flag_clear_explicit(ptr, memorder) \
1095c381a35STyler Retzlaff 	atomic_flag_clear_explicit(ptr, memorder)
1105c381a35STyler Retzlaff 
1115c381a35STyler Retzlaff /* We provide internal macro here to allow conditional expansion
1125c381a35STyler Retzlaff  * in the body of the per-arch rte_atomic_thread_fence inline functions.
1135c381a35STyler Retzlaff  */
1145c381a35STyler Retzlaff #define __rte_atomic_thread_fence(memorder) \
1155c381a35STyler Retzlaff 	atomic_thread_fence(memorder)
1165c381a35STyler Retzlaff 
1175c381a35STyler Retzlaff #else /* !RTE_ENABLE_STDATOMIC */
1185c381a35STyler Retzlaff 
1195c381a35STyler Retzlaff #define RTE_ATOMIC(type) type
1205c381a35STyler Retzlaff 
1215c381a35STyler Retzlaff #define __rte_atomic
1225c381a35STyler Retzlaff 
1235c381a35STyler Retzlaff /* The memory order is an integer type in GCC built-ins,
1245c381a35STyler Retzlaff  * not an enumerated type like in C11.
1255c381a35STyler Retzlaff  */
1265c381a35STyler Retzlaff typedef int rte_memory_order;
1275c381a35STyler Retzlaff 
1285c381a35STyler Retzlaff #define rte_memory_order_relaxed __ATOMIC_RELAXED
1295c381a35STyler Retzlaff #define rte_memory_order_consume __ATOMIC_CONSUME
1305c381a35STyler Retzlaff #define rte_memory_order_acquire __ATOMIC_ACQUIRE
1315c381a35STyler Retzlaff #define rte_memory_order_release __ATOMIC_RELEASE
1325c381a35STyler Retzlaff #define rte_memory_order_acq_rel __ATOMIC_ACQ_REL
1335c381a35STyler Retzlaff #define rte_memory_order_seq_cst __ATOMIC_SEQ_CST
1345c381a35STyler Retzlaff 
1355c381a35STyler Retzlaff #define rte_atomic_load_explicit(ptr, memorder) \
1365c381a35STyler Retzlaff 	__atomic_load_n(ptr, memorder)
1375c381a35STyler Retzlaff 
1385c381a35STyler Retzlaff #define rte_atomic_store_explicit(ptr, val, memorder) \
1395c381a35STyler Retzlaff 	__atomic_store_n(ptr, val, memorder)
1405c381a35STyler Retzlaff 
1415c381a35STyler Retzlaff #define rte_atomic_exchange_explicit(ptr, val, memorder) \
1425c381a35STyler Retzlaff 	__atomic_exchange_n(ptr, val, memorder)
1435c381a35STyler Retzlaff 
1445c381a35STyler Retzlaff #define rte_atomic_compare_exchange_strong_explicit(ptr, expected, desired, \
1455c381a35STyler Retzlaff 		succ_memorder, fail_memorder) \
1465c381a35STyler Retzlaff 	__atomic_compare_exchange_n(ptr, expected, desired, 0, \
1475c381a35STyler Retzlaff 		succ_memorder, fail_memorder)
1485c381a35STyler Retzlaff 
1495c381a35STyler Retzlaff #define rte_atomic_compare_exchange_weak_explicit(ptr, expected, desired, \
1505c381a35STyler Retzlaff 		succ_memorder, fail_memorder) \
1515c381a35STyler Retzlaff 	__atomic_compare_exchange_n(ptr, expected, desired, 1, \
1525c381a35STyler Retzlaff 		succ_memorder, fail_memorder)
1535c381a35STyler Retzlaff 
1545c381a35STyler Retzlaff #define rte_atomic_fetch_add_explicit(ptr, val, memorder) \
1555c381a35STyler Retzlaff 	__atomic_fetch_add(ptr, val, memorder)
1565c381a35STyler Retzlaff 
1575c381a35STyler Retzlaff #define rte_atomic_fetch_sub_explicit(ptr, val, memorder) \
1585c381a35STyler Retzlaff 	__atomic_fetch_sub(ptr, val, memorder)
1595c381a35STyler Retzlaff 
1605c381a35STyler Retzlaff #define rte_atomic_fetch_and_explicit(ptr, val, memorder) \
1615c381a35STyler Retzlaff 	__atomic_fetch_and(ptr, val, memorder)
1625c381a35STyler Retzlaff 
1635c381a35STyler Retzlaff #define rte_atomic_fetch_xor_explicit(ptr, val, memorder) \
1645c381a35STyler Retzlaff 	__atomic_fetch_xor(ptr, val, memorder)
1655c381a35STyler Retzlaff 
1665c381a35STyler Retzlaff #define rte_atomic_fetch_or_explicit(ptr, val, memorder) \
1675c381a35STyler Retzlaff 	__atomic_fetch_or(ptr, val, memorder)
1685c381a35STyler Retzlaff 
1695c381a35STyler Retzlaff #define rte_atomic_fetch_nand_explicit(ptr, val, memorder) \
1705c381a35STyler Retzlaff 	__atomic_fetch_nand(ptr, val, memorder)
1715c381a35STyler Retzlaff 
1725c381a35STyler Retzlaff #define rte_atomic_flag_test_and_set_explicit(ptr, memorder) \
1735c381a35STyler Retzlaff 	__atomic_test_and_set(ptr, memorder)
1745c381a35STyler Retzlaff 
1755c381a35STyler Retzlaff #define rte_atomic_flag_clear_explicit(ptr, memorder) \
1765c381a35STyler Retzlaff 	__atomic_clear(ptr, memorder)
1775c381a35STyler Retzlaff 
1785c381a35STyler Retzlaff /* We provide internal macro here to allow conditional expansion
1795c381a35STyler Retzlaff  * in the body of the per-arch rte_atomic_thread_fence inline functions.
1805c381a35STyler Retzlaff  */
1815c381a35STyler Retzlaff #define __rte_atomic_thread_fence(memorder) \
1825c381a35STyler Retzlaff 	__atomic_thread_fence(memorder)
1835c381a35STyler Retzlaff 
1845c381a35STyler Retzlaff #endif
1855c381a35STyler Retzlaff 
1865c381a35STyler Retzlaff #endif /* RTE_STDATOMIC_H */
187