From 13cb8f76da9d9420330796f469dbf10643ba5b12 Mon Sep 17 00:00:00 2001 From: Torvald Riegel Date: Thu, 26 May 2016 00:57:27 +0200 Subject: [PATCH] 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. --- ChangeLog | 6 ++++++ include/atomic.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/ChangeLog b/ChangeLog index d8ba9cd57d..6a3637cb24 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-06 Christian Seiler [BZ #20444] diff --git a/include/atomic.h b/include/atomic.h index 129ee24426..5a8e7e7966 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 */