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