From b85e30e655027132c4326d2fdde010c517165aaf Mon Sep 17 00:00:00 2001 From: Catalin Enache Date: Fri, 30 Jun 2017 14:27:34 +0300 Subject: [PATCH 2/6] Add atomic operations required by the new condition variable. * include/atomic.h (atomic_fetch_and_relaxed, atomic_fetch_and_release, atomic_fetch_or_release, atomic_fetch_xor_release): New. Upstream-Status: Backport Author: Torvald Riegel Signed-off-by: Catalin Enache --- ChangeLog | 6 ++++++ include/atomic.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/ChangeLog b/ChangeLog index cb87279..96b6da2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2016-08-09 Torvald Riegel + + * include/atomic.h (atomic_fetch_and_relaxed, + atomic_fetch_and_release, atomic_fetch_or_release, + atomic_fetch_xor_release): New. + 2016-08-05 Torvald Riegel * include/atomic.h (atomic_exchange_relaxed): New. diff --git a/include/atomic.h b/include/atomic.h index 129ee24..5a8e7e7 100644 --- a/include/atomic.h +++ b/include/atomic.h @@ -611,9 +611,15 @@ void __atomic_link_error (void); ({ __atomic_check_size((mem)); \ __atomic_fetch_add ((mem), (operand), __ATOMIC_ACQ_REL); }) +# define atomic_fetch_and_relaxed(mem, operand) \ + ({ __atomic_check_size((mem)); \ + __atomic_fetch_and ((mem), (operand), __ATOMIC_RELAXED); }) # define atomic_fetch_and_acquire(mem, operand) \ ({ __atomic_check_size((mem)); \ __atomic_fetch_and ((mem), (operand), __ATOMIC_ACQUIRE); }) +# define atomic_fetch_and_release(mem, operand) \ + ({ __atomic_check_size((mem)); \ + __atomic_fetch_and ((mem), (operand), __ATOMIC_RELEASE); }) # define atomic_fetch_or_relaxed(mem, operand) \ ({ __atomic_check_size((mem)); \ @@ -621,6 +627,13 @@ void __atomic_link_error (void); # define atomic_fetch_or_acquire(mem, operand) \ ({ __atomic_check_size((mem)); \ __atomic_fetch_or ((mem), (operand), __ATOMIC_ACQUIRE); }) +# define atomic_fetch_or_release(mem, operand) \ + ({ __atomic_check_size((mem)); \ + __atomic_fetch_or ((mem), (operand), __ATOMIC_RELEASE); }) + +# define atomic_fetch_xor_release(mem, operand) \ + ({ __atomic_check_size((mem)); \ + __atomic_fetch_xor ((mem), (operand), __ATOMIC_RELEASE); }) #else /* !USE_ATOMIC_COMPILER_BUILTINS */ @@ -724,12 +737,24 @@ void __atomic_link_error (void); atomic_exchange_and_add_acq ((mem), (operand)); }) # endif +/* XXX Fall back to acquire MO because archs do not define a weaker + atomic_and_val. */ +# ifndef atomic_fetch_and_relaxed +# define atomic_fetch_and_relaxed(mem, operand) \ + atomic_fetch_and_acquire ((mem), (operand)) +# endif /* XXX The default for atomic_and_val has acquire semantics, but this is not documented. */ # ifndef atomic_fetch_and_acquire # define atomic_fetch_and_acquire(mem, operand) \ atomic_and_val ((mem), (operand)) # endif +# ifndef atomic_fetch_and_release +/* XXX This unnecessarily has acquire MO. */ +# define atomic_fetch_and_release(mem, operand) \ + ({ atomic_thread_fence_release (); \ + atomic_and_val ((mem), (operand)); }) +# endif /* XXX The default for atomic_or_val has acquire semantics, but this is not documented. */ @@ -743,6 +768,28 @@ void __atomic_link_error (void); # define atomic_fetch_or_relaxed(mem, operand) \ atomic_fetch_or_acquire ((mem), (operand)) # endif +/* XXX Contains an unnecessary acquire MO because archs do not define a weaker + atomic_or_val. */ +# ifndef atomic_fetch_or_release +# define atomic_fetch_or_release(mem, operand) \ + ({ atomic_thread_fence_release (); \ + atomic_fetch_or_acquire ((mem), (operand)); }) +# endif + +# ifndef atomic_fetch_xor_release +# define atomic_fetch_xor_release(mem, operand) \ + ({ __typeof (*(mem)) __atg104_old; \ + __typeof (mem) __atg104_memp = (mem); \ + __typeof (*(mem)) __atg104_op = (operand); \ + \ + do \ + __atg104_old = (*__atg104_memp); \ + while (__builtin_expect \ + (atomic_compare_and_exchange_bool_rel ( \ + __atg104_memp, __atg104_old ^ __atg104_op, __atg104_old), 0));\ + \ + __atg104_old; }) +#endif #endif /* !USE_ATOMIC_COMPILER_BUILTINS */ -- 2.10.2