]> git.lttng.org Git - urcu.git/commitdiff
Introduce _CMM_TOOLCHAIN_SUPPORT_C11_MM
authorOlivier Dion <odion@efficios.com>
Mon, 21 Oct 2024 17:31:28 +0000 (13:31 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 2 Dec 2024 18:17:57 +0000 (13:17 -0500)
If the toolchain used supports the C11 memory model, define the private
_CMM_TOOLCHAIN_SUPPORT_C11_MM macro.

This is used to implement `uatomic_load()/uatomic_store' in term of
`__atomic' builtins instead of using volatile accesses, therefore
reducing possible redundant memory barriers for some memory orders.

Change-Id: I0df3c202daf74ac012338583b761de15687d25f3
Signed-off-by: Olivier Dion <odion@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/urcu/compiler.h
include/urcu/uatomic.h
include/urcu/uatomic/generic.h

index 31a474c9c86c2d9af1f118fccedc18f40d6faff0..0e94d2f87ff2dd4065bb168dc2f601fe1bdea362 100644 (file)
  */
 #define CMM_ACCESS_ONCE(x)     (*(__volatile__  __typeof__(x) *)&(x))
 
+/*
+ * If the toolchain support the C11 memory model, define the private macro
+ * _CMM_TOOLCHAIN_SUPPORT_C11_MM.
+ */
+#if ((defined (__cplusplus) && __cplusplus >= 201103L) ||              \
+       (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L))
+# define _CMM_TOOLCHAIN_SUPPORT_C11_MM
+#elif defined(CONFIG_RCU_USE_ATOMIC_BUILTINS)
+#  error "URCU was configured to use atomic builtins, but this toolchain does not support them."
+#endif
+
 #ifndef caa_max
 #define caa_max(a,b) ((a)>(b)?(a):(b))
 #endif
index 69154d37a35d6003a283e058df66ecb04756ce44..1af3cd898ebe123ca42fec0282f9c115c225f994 100644 (file)
@@ -19,7 +19,7 @@ enum cmm_memorder {
        CMM_SEQ_CST_FENCE = 6,
 };
 
-#ifdef CONFIG_RCU_USE_ATOMIC_BUILTINS
+#if defined(_CMM_TOOLCHAIN_SUPPORT_C11_MM)
 
 /*
  * Make sure that CMM_SEQ_CST_FENCE is not equivalent to other memory orders.
index 24a025fc92d1285130efa55d5b994cec10eef362..e32f1798ba7efe9f65397ee43770dc6d5b26ffb4 100644 (file)
@@ -77,21 +77,39 @@ extern "C" {
        } while(0)
 #endif /* _cmm_compat_c11_smp_mb__after_mo */
 
+/*
+ * If the toolchain supports the C11 memory model, then it is safe to implement
+ * `uatomic_store_mo()' in term of __atomic builtins.  This has the effect of
+ * reducing the number of emitted memory barriers except for the
+ * CMM_SEQ_CST_FENCE memory order.
+ */
+#ifndef uatomic_store_mo
+#  ifdef _CMM_TOOLCHAIN_SUPPORT_C11_MM
+#    define uatomic_store_mo(addr, v, mo)                      \
        do {                                                    \
-               _cmm_compat_c11_smp_mb__before_mo(op, mo);      \
-               op(addr, v);                                    \
-               _cmm_compat_c11_smp_mb__after_mo(op, mo);       \
+               __atomic_store_n(cmm_cast_volatile(addr), v,    \
+                               cmm_to_c11(mo));                \
+               cmm_seq_cst_fence_after_atomic(mo);             \
        } while (0)
-
-#define uatomic_store_mo(addr, v, mo)                                  \
+#  else
+#    define uatomic_store_mo(addr, v, mo)                              \
        do {                                                            \
-               _cmm_compat_c11_smp_mb__before_mo(uatomic_set, mo);     \
-               uatomic_set(addr, v);                                   \
-               _cmm_compat_c11_smp_mb__after_mo(uatomic_set, mo);      \
+               _cmm_compat_c11_smp_mb__before_mo(uatomic_store, mo);   \
+               (void) CMM_STORE_SHARED(addr, v);                       \
+               _cmm_compat_c11_smp_mb__after_mo(uatomic_store, mo);    \
        } while (0)
+#  endif  /* _CMM_TOOLCHAIN_SUPPORT_C11_MM */
+#endif /* !uatomic_store */
 
 /*
+ * If the toolchain supports the C11 memory model, then it is safe to implement
+ * `uatomic_load_mo()' in term of __atomic builtins.  This has the effect of
+ * reducing the number of emitted memory barriers except for the
+ * CMM_SEQ_CST_FENCE memory order.
  */
+#ifndef uatomic_load_mo
+#  ifdef _CMM_TOOLCHAIN_SUPPORT_C11_MM
+#    define uatomic_load_mo(addr, mo)                                  \
        __extension__                                                   \
        ({                                                              \
                __typeof__(*(addr)) _value =                            \
@@ -101,17 +119,18 @@ extern "C" {
                                                                        \
                _value;                                                 \
        })
-
-
-#define uatomic_load_mo(addr, mo)                                              \
+#  else
+#    define uatomic_load_mo(addr, mo)                                  \
        __extension__                                                   \
        ({                                                              \
-               _cmm_compat_c11_smp_mb__before_mo(uatomic_read, mo);    \
-               __typeof__(*(addr)) _rcu_value = uatomic_read(addr);    \
-               _cmm_compat_c11_smp_mb__after_mo(uatomic_read, mo);     \
+               _cmm_compat_c11_smp_mb__before_mo(uatomic_load, mo);    \
+               __typeof__(*(addr)) _rcu_value = CMM_LOAD_SHARED(addr); \
+               _cmm_compat_c11_smp_mb__after_mo(uatomic_load, mo);     \
                                                                        \
                _rcu_value;                                             \
        })
+#  endif  /* _CMM_TOOLCHAIN_SUPPORT_C11_MM */
+#endif /* !uatomic_load */
 
 #if !defined __OPTIMIZE__  || defined UATOMIC_NO_LINK_ERROR
 #ifdef ILLEGAL_INSTR
This page took 0.03617 seconds and 4 git commands to generate.