[lttng-dev] [PATCH 02/11] urcu/uatomic: Use atomic builtins if configured

Olivier Dion odion at efficios.com
Mon May 15 16:17:09 EDT 2023


Implement uatomic in term of atomic builtins if configured to do so.

Change-Id: I5814494c62ee507fd5d381c3ba4ccd0a80c4f4e3
Co-authored-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
Signed-off-by: Olivier Dion <odion at efficios.com>
---
 include/Makefile.am                     |  3 +
 include/urcu/uatomic.h                  |  5 +-
 include/urcu/uatomic/builtins-generic.h | 85 +++++++++++++++++++++++++
 include/urcu/uatomic/builtins-x86.h     | 85 +++++++++++++++++++++++++
 include/urcu/uatomic/builtins.h         | 83 ++++++++++++++++++++++++
 5 files changed, 260 insertions(+), 1 deletion(-)
 create mode 100644 include/urcu/uatomic/builtins-generic.h
 create mode 100644 include/urcu/uatomic/builtins-x86.h
 create mode 100644 include/urcu/uatomic/builtins.h

diff --git a/include/Makefile.am b/include/Makefile.am
index ba1fe60..fac941f 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -63,6 +63,9 @@ nobase_include_HEADERS = \
 	urcu/uatomic/alpha.h \
 	urcu/uatomic_arch.h \
 	urcu/uatomic/arm.h \
+	urcu/uatomic/builtins.h \
+	urcu/uatomic/builtins-generic.h \
+	urcu/uatomic/builtins-x86.h \
 	urcu/uatomic/gcc.h \
 	urcu/uatomic/generic.h \
 	urcu/uatomic.h \
diff --git a/include/urcu/uatomic.h b/include/urcu/uatomic.h
index 2fb5fd4..6b57c5f 100644
--- a/include/urcu/uatomic.h
+++ b/include/urcu/uatomic.h
@@ -22,8 +22,11 @@
 #define _URCU_UATOMIC_H
 
 #include <urcu/arch.h>
+#include <urcu/config.h>
 
-#if defined(URCU_ARCH_X86)
+#if defined(CONFIG_RCU_USE_ATOMIC_BUILTINS)
+#include <urcu/uatomic/builtins.h>
+#elif defined(URCU_ARCH_X86)
 #include <urcu/uatomic/x86.h>
 #elif defined(URCU_ARCH_PPC)
 #include <urcu/uatomic/ppc.h>
diff --git a/include/urcu/uatomic/builtins-generic.h b/include/urcu/uatomic/builtins-generic.h
new file mode 100644
index 0000000..8e6a9b5
--- /dev/null
+++ b/include/urcu/uatomic/builtins-generic.h
@@ -0,0 +1,85 @@
+/*
+ * urcu/uatomic/builtins-generic.h
+ *
+ * Copyright (c) 2023 Olivier Dion <odion at efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _URCU_UATOMIC_BUILTINS_GENERIC_H
+#define _URCU_UATOMIC_BUILTINS_GENERIC_H
+
+#include <urcu/system.h>
+
+#define uatomic_set(addr, v) __atomic_store_n(addr, v, __ATOMIC_RELAXED)
+
+#define uatomic_read(addr) __atomic_load_n(addr, __ATOMIC_RELAXED)
+
+#define uatomic_cmpxchg(addr, old, new)					\
+	__extension__							\
+	({								\
+		__typeof__(*(addr)) _old = (__typeof__(*(addr)))old;	\
+		__atomic_compare_exchange_n(addr, &_old, new, 0,	\
+					    __ATOMIC_SEQ_CST,		\
+					    __ATOMIC_SEQ_CST);		\
+		_old;							\
+	})
+
+#define uatomic_xchg(addr, v)				\
+	__atomic_exchange_n(addr, v, __ATOMIC_SEQ_CST)
+
+#define uatomic_add_return(addr, v)			\
+	__atomic_add_fetch(addr, v, __ATOMIC_SEQ_CST)
+
+#define uatomic_sub_return(addr, v)			\
+	__atomic_sub_fetch(addr, v, __ATOMIC_SEQ_CST)
+
+#define uatomic_and(addr, mask)					\
+	(void)__atomic_and_fetch(addr, mask, __ATOMIC_RELAXED)
+
+#define uatomic_or(addr, mask)					\
+	(void)__atomic_or_fetch(addr, mask, __ATOMIC_RELAXED)
+
+#define uatomic_add(addr, v)					\
+	(void)__atomic_add_fetch(addr, v, __ATOMIC_RELAXED)
+
+#define uatomic_sub(addr, v)					\
+	(void)__atomic_sub_fetch(addr, v, __ATOMIC_RELAXED)
+
+#define uatomic_inc(addr)					\
+	(void)__atomic_add_fetch(addr, 1, __ATOMIC_RELAXED)
+
+#define uatomic_dec(addr)					\
+	(void)__atomic_sub_fetch(addr, 1, __ATOMIC_RELAXED)
+
+#define cmm_smp_mb__before_uatomic_and() cmm_smp_mb()
+#define cmm_smp_mb__after_uatomic_and()  cmm_smp_mb()
+
+#define cmm_smp_mb__before_uatomic_or() cmm_smp_mb()
+#define cmm_smp_mb__after_uatomic_or()  cmm_smp_mb()
+
+#define cmm_smp_mb__before_uatomic_add() cmm_smp_mb()
+#define cmm_smp_mb__after_uatomic_add()  cmm_smp_mb()
+
+#define cmm_smp_mb__before_uatomic_sub() cmm_smp_mb()
+#define cmm_smp_mb__after_uatomic_sub()  cmm_smp_mb()
+
+#define cmm_smp_mb__before_uatomic_inc() cmm_smp_mb()
+#define cmm_smp_mb__after_uatomic_inc() cmm_smp_mb()
+
+#define cmm_smp_mb__before_uatomic_dec() cmm_smp_mb()
+#define cmm_smp_mb__after_uatomic_dec() cmm_smp_mb()
+
+#endif /* _URCU_UATOMIC_BUILTINS_GENERIC_H */
diff --git a/include/urcu/uatomic/builtins-x86.h b/include/urcu/uatomic/builtins-x86.h
new file mode 100644
index 0000000..a70f922
--- /dev/null
+++ b/include/urcu/uatomic/builtins-x86.h
@@ -0,0 +1,85 @@
+/*
+ * urcu/uatomic/builtins-x86.h
+ *
+ * Copyright (c) 2023 Olivier Dion <odion at efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _URCU_UATOMIC_BUILTINS_X86_H
+#define _URCU_UATOMIC_BUILTINS_X86_H
+
+#include <urcu/system.h>
+
+#define uatomic_set(addr, v) __atomic_store_n(addr, v, __ATOMIC_RELAXED)
+
+#define uatomic_read(addr) __atomic_load_n(addr, __ATOMIC_RELAXED)
+
+#define uatomic_cmpxchg(addr, old, new)					\
+	__extension__							\
+	({								\
+		__typeof__(*(addr)) _old = (__typeof__(*(addr)))old;	\
+		__atomic_compare_exchange_n(addr, &_old, new, 0,	\
+					    __ATOMIC_SEQ_CST,		\
+					    __ATOMIC_SEQ_CST);		\
+		_old;							\
+	})
+
+#define uatomic_xchg(addr, v)				\
+	__atomic_exchange_n(addr, v, __ATOMIC_SEQ_CST)
+
+#define uatomic_add_return(addr, v)			\
+	__atomic_add_fetch(addr, v, __ATOMIC_SEQ_CST)
+
+#define uatomic_sub_return(addr, v)			\
+	__atomic_sub_fetch(addr, v, __ATOMIC_SEQ_CST)
+
+#define uatomic_and(addr, mask)					\
+	(void)__atomic_and_fetch(addr, mask, __ATOMIC_SEQ_CST)
+
+#define uatomic_or(addr, mask)					\
+	(void)__atomic_or_fetch(addr, mask, __ATOMIC_SEQ_CST)
+
+#define uatomic_add(addr, v)					\
+	(void)__atomic_add_fetch(addr, v, __ATOMIC_SEQ_CST)
+
+#define uatomic_sub(addr, v)					\
+	(void)__atomic_sub_fetch(addr, v, __ATOMIC_SEQ_CST)
+
+#define uatomic_inc(addr)					\
+	(void)__atomic_add_fetch(addr, 1, __ATOMIC_SEQ_CST)
+
+#define uatomic_dec(addr)					\
+	(void)__atomic_sub_fetch(addr, 1, __ATOMIC_SEQ_CST)
+
+#define cmm_smp_mb__before_uatomic_and() do { } while (0)
+#define cmm_smp_mb__after_uatomic_and()  do { } while (0)
+
+#define cmm_smp_mb__before_uatomic_or() do { } while (0)
+#define cmm_smp_mb__after_uatomic_or()  do { } while (0)
+
+#define cmm_smp_mb__before_uatomic_add() do { } while (0)
+#define cmm_smp_mb__after_uatomic_add()  do { } while (0)
+
+#define cmm_smp_mb__before_uatomic_sub() do { } while (0)
+#define cmm_smp_mb__after_uatomic_sub()  do { } while (0)
+
+#define cmm_smp_mb__before_uatomic_inc() do { } while (0)
+#define cmm_smp_mb__after_uatomic_inc()  do { } while (0)
+
+#define cmm_smp_mb__before_uatomic_dec() do { } while (0)
+#define cmm_smp_mb__after_uatomic_dec()  do { } while (0)
+
+#endif /* _URCU_UATOMIC_BUILTINS_X86_H */
diff --git a/include/urcu/uatomic/builtins.h b/include/urcu/uatomic/builtins.h
new file mode 100644
index 0000000..164201b
--- /dev/null
+++ b/include/urcu/uatomic/builtins.h
@@ -0,0 +1,83 @@
+/*
+ * urcu/uatomic/builtins.h
+ *
+ * Copyright (c) 2023 Olivier Dion <odion at efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _URCU_UATOMIC_BUILTINS_H
+#define _URCU_UATOMIC_BUILTINS_H
+
+#include <urcu/arch.h>
+
+#if defined(__has_builtin)
+#  if !__has_builtin(__atomic_store_n)
+#    error "Toolchain does not support __atomic_store_n."
+#  endif
+#  if !__has_builtin(__atomic_load_n)
+#    error "Toolchain does not support __atomic_load_n."
+#  endif
+#  if !__has_builtin(__atomic_exchange_n)
+#    error "Toolchain does not support __atomic_exchange_n."
+#  endif
+#  if !__has_builtin(__atomic_compare_exchange_n)
+#    error "Toolchain does not support __atomic_compare_exchange_n."
+#  endif
+#  if !__has_builtin(__atomic_add_fetch)
+#    error "Toolchain does not support __atomic_add_fetch."
+#  endif
+#  if !__has_builtin(__atomic_sub_fetch)
+#    error "Toolchain does not support __atomic_sub_fetch."
+#  endif
+#  if !__has_builtin(__atomic_or_fetch)
+#    error "Toolchain does not support __atomic_or_fetch."
+#  endif
+#  if !__has_builtin(__atomic_thread_fence)
+#    error "Toolchain does not support __atomic_thread_fence."
+#  endif
+#  if !__has_builtin(__atomic_signal_fence)
+#    error "Toolchain does not support __atomic_signal_fence."
+#  endif
+#elif defined(__GNUC__)
+#  define GCC_VERSION (__GNUC__       * 10000 + \
+		       __GNUC_MINOR__ * 100   + \
+		       __GNUC_PATCHLEVEL__)
+#  if  GCC_VERSION < 40700
+#    error "GCC version is too old. Version must be 4.7 or greater"
+#  endif
+#  undef  GCC_VERSION
+#else
+#  error "Toolchain is not supported."
+#endif
+
+#if defined(__GNUC__)
+#  define UATOMIC_HAS_ATOMIC_BYTE  __GCC_ATOMIC_CHAR_LOCK_FREE
+#  define UATOMIC_HAS_ATOMIC_SHORT __GCC_ATOMIC_SHORT_LOCK_FREE
+#elif defined(__clang__)
+#  define UATOMIC_HAS_ATOMIC_BYTE  __CLANG_ATOMIC_CHAR_LOCK_FREE
+#  define UATOMIC_HAS_ATOMIC_SHORT __CLANG_ATOMIC_SHORT_LOCK_FREE
+#else
+/* #  define UATOMIC_HAS_ATOMIC_BYTE  */
+/* #  define UATOMIC_HAS_ATOMIC_SHORT */
+#endif
+
+#if defined(URCU_ARCH_X86)
+#  include <urcu/uatomic/builtins-x86.h>
+#else
+#  include <urcu/uatomic/builtins-generic.h>
+#endif
+
+#endif	/* _URCU_UATOMIC_BUILTINS_H */
-- 
2.39.2



More information about the lttng-dev mailing list