1 // SPDX-FileCopyrightText: 2020 Michael Jeanson <mjeanson (at) efficios.com> 2 // 3 // SPDX-License-Identifier: LGPL-2.1-or-later 4 5 #ifndef _URCU_UATOMIC_H 6 #define _URCU_UATOMIC_H 7 8 #include <urcu/arch.h> 9 #include <urcu/compiler.h> 10 #include <urcu/config.h> 11 12 enum cmm_memorder { 13 CMM_RELAXED = 0, 14 CMM_CONSUME = 1, 15 CMM_ACQUIRE = 2, 16 CMM_RELEASE = 3, 17 CMM_ACQ_REL = 4, 18 CMM_SEQ_CST = 5, 19 CMM_SEQ_CST_FENCE = 6, 20 }; 21 22 #if defined(_CMM_TOOLCHAIN_SUPPORT_C11_MM) 23 24 /* 25 * Make sure that CMM_SEQ_CST_FENCE is not equivalent to other memory orders. 26 */ 27 urcu_static_assert(CMM_RELAXED == __ATOMIC_RELAXED, "CMM_RELAXED vs __ATOMIC_RELAXED values mismatch", cmm_relaxed_values_mismatch); 28 urcu_static_assert(CMM_CONSUME == __ATOMIC_CONSUME, "CMM_CONSUME vs __ATOMIC_CONSUME values mismatch", cmm_consume_values_mismatch); 29 urcu_static_assert(CMM_ACQUIRE == __ATOMIC_ACQUIRE, "CMM_ACQUIRE vs __ATOMIC_ACQUIRE values mismatch", cmm_acquire_values_mismatch); 30 urcu_static_assert(CMM_RELEASE == __ATOMIC_RELEASE, "CMM_RELEASE vs __ATOMIC_RELEASE values mismatch", cmm_release_values_mismatch); 31 urcu_static_assert(CMM_ACQ_REL == __ATOMIC_ACQ_REL, "CMM_ACQ_REL vs __ATOMIC_ACQ_REL values mismatch", cmm_acq_rel_values_mismatch); 32 urcu_static_assert(CMM_SEQ_CST == __ATOMIC_SEQ_CST, "CMM_SEQ_CST vs __ATOMIC_SEQ_CST values mismatch", cmm_seq_cst_values_mismatch); 33 34 /* 35 * This is not part of the public API. It it used internally to implement the 36 * CMM_SEQ_CST_FENCE memory order. 37 * 38 * NOTE: Using switch here instead of if statement to avoid -Wduplicated-cond 39 * warning when memory order is conditionally determined. 40 */ 41 static inline void cmm_seq_cst_fence_after_atomic(enum cmm_memorder mo) 42 { 43 switch (mo) { 44 case CMM_SEQ_CST_FENCE: 45 cmm_smp_mb(); 46 break; 47 default: 48 break; 49 } 50 } 51 52 #endif 53 54 /* 55 * This is not part of the public API. It is used internally to convert from the 56 * CMM memory model to the C11 memory model. 57 */ 58 static inline int cmm_to_c11(int mo) 59 { 60 if (mo == CMM_SEQ_CST_FENCE) { 61 return CMM_SEQ_CST; 62 } 63 return mo; 64 } 65 66 #include <urcu/uatomic/api.h> 67 68 #if defined(CONFIG_RCU_USE_ATOMIC_BUILTINS) 69 #include <urcu/uatomic/builtins.h> 70 #elif defined(URCU_ARCH_X86) 71 #include <urcu/uatomic/x86.h> 72 #elif defined(URCU_ARCH_PPC) 73 #include <urcu/uatomic/ppc.h> 74 #elif defined(URCU_ARCH_S390) 75 #include <urcu/uatomic/s390.h> 76 #elif defined(URCU_ARCH_SPARC64) 77 #include <urcu/uatomic/sparc64.h> 78 #elif defined(URCU_ARCH_ALPHA) 79 #include <urcu/uatomic/alpha.h> 80 #elif defined(URCU_ARCH_IA64) 81 #include <urcu/uatomic/ia64.h> 82 #elif defined(URCU_ARCH_ARM) 83 #include <urcu/uatomic/arm.h> 84 #elif defined(URCU_ARCH_AARCH64) 85 #include <urcu/uatomic/aarch64.h> 86 #elif defined(URCU_ARCH_MIPS) 87 #include <urcu/uatomic/mips.h> 88 #elif defined(URCU_ARCH_NIOS2) 89 #include <urcu/uatomic/nios2.h> 90 #elif defined(URCU_ARCH_TILE) 91 #include <urcu/uatomic/tile.h> 92 #elif defined(URCU_ARCH_HPPA) 93 #include <urcu/uatomic/hppa.h> 94 #elif defined(URCU_ARCH_M68K) 95 #include <urcu/uatomic/m68k.h> 96 #elif defined(URCU_ARCH_RISCV) 97 #include <urcu/uatomic/riscv.h> 98 #elif defined(URCU_ARCH_LOONGARCH) 99 #include <urcu/uatomic/loongarch.h> 100 #elif defined(URCU_ARCH_SH3) 101 #include <urcu/uatomic/sh3.h> 102 #elif defined(URCU_ARCH_VAX) 103 #include <urcu/uatomic/vax.h> 104 #else 105 #error "Cannot build: unrecognized architecture, see <urcu/arch.h>." 106 #endif 107 108 #endif /* _URCU_UATOMIC_H */ 109