Implement uatomic in term of atomic builtins if configured to do so. Change-Id: I5814494c62ee507fd5d381c3ba4ccd0a80c4f4e3 Co-authored-by: Mathieu Desnoyers <mathieu.desnoy...@efficios.com> Signed-off-by: Olivier Dion <od...@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 <od...@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 <od...@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 <od...@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 _______________________________________________ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev