Commit | Line | Data |
---|---|---|
d3d3857f MJ |
1 | // SPDX-FileCopyrightText: 2020 Michael Jeanson <mjeanson@efficios.com> |
2 | // | |
3 | // SPDX-License-Identifier: LGPL-2.1-or-later | |
0b1e236d MJ |
4 | |
5 | #ifndef _URCU_UATOMIC_H | |
6 | #define _URCU_UATOMIC_H | |
7 | ||
8 | #include <urcu/arch.h> | |
455a8429 | 9 | #include <urcu/compiler.h> |
d1854484 OD |
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 | #ifdef CONFIG_RCU_USE_ATOMIC_BUILTINS | |
23 | ||
24 | /* | |
25 | * Make sure that CMM_SEQ_CST_FENCE is not equivalent to other memory orders. | |
26 | */ | |
843860fe MD |
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); | |
d1854484 OD |
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 | } | |
0b1e236d | 65 | |
d1854484 OD |
66 | #if defined(CONFIG_RCU_USE_ATOMIC_BUILTINS) |
67 | #include <urcu/uatomic/builtins.h> | |
68 | #elif defined(URCU_ARCH_X86) | |
0b1e236d MJ |
69 | #include <urcu/uatomic/x86.h> |
70 | #elif defined(URCU_ARCH_PPC) | |
71 | #include <urcu/uatomic/ppc.h> | |
72 | #elif defined(URCU_ARCH_S390) | |
73 | #include <urcu/uatomic/s390.h> | |
74 | #elif defined(URCU_ARCH_SPARC64) | |
75 | #include <urcu/uatomic/sparc64.h> | |
76 | #elif defined(URCU_ARCH_ALPHA) | |
77 | #include <urcu/uatomic/alpha.h> | |
78 | #elif defined(URCU_ARCH_IA64) | |
79 | #include <urcu/uatomic/ia64.h> | |
80 | #elif defined(URCU_ARCH_ARM) | |
81 | #include <urcu/uatomic/arm.h> | |
82 | #elif defined(URCU_ARCH_AARCH64) | |
83 | #include <urcu/uatomic/aarch64.h> | |
84 | #elif defined(URCU_ARCH_MIPS) | |
85 | #include <urcu/uatomic/mips.h> | |
86 | #elif defined(URCU_ARCH_NIOS2) | |
87 | #include <urcu/uatomic/nios2.h> | |
88 | #elif defined(URCU_ARCH_TILE) | |
89 | #include <urcu/uatomic/tile.h> | |
90 | #elif defined(URCU_ARCH_HPPA) | |
91 | #include <urcu/uatomic/hppa.h> | |
92 | #elif defined(URCU_ARCH_M68K) | |
93 | #include <urcu/uatomic/m68k.h> | |
94 | #elif defined(URCU_ARCH_RISCV) | |
95 | #include <urcu/uatomic/riscv.h> | |
96 | #else | |
97 | #error "Cannot build: unrecognized architecture, see <urcu/arch.h>." | |
98 | #endif | |
99 | ||
100 | #endif /* _URCU_UATOMIC_H */ |