diff options
author | Torvald Riegel <triegel@redhat.com> | 2016-05-26 00:57:27 +0200 |
---|---|---|
committer | Torvald Riegel <triegel@redhat.com> | 2016-08-09 12:13:11 +0200 |
commit | 13cb8f76da9d9420330796f469dbf10643ba5b12 (patch) | |
tree | ef8baa9e549aacfe904590d03001fd383677244e /include | |
parent | a194625ef31f0c33afae9b53e2dfaa17c2517606 (diff) | |
download | glibc-13cb8f76da9d9420330796f469dbf10643ba5b12.tar.gz glibc-13cb8f76da9d9420330796f469dbf10643ba5b12.tar.xz glibc-13cb8f76da9d9420330796f469dbf10643ba5b12.zip |
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.
Diffstat (limited to 'include')
-rw-r--r-- | include/atomic.h | 47 |
1 files changed, 47 insertions, 0 deletions
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 */ |