olga / rpms / glibc

Forked from rpms/glibc 5 years ago
Clone

Blame SOURCES/glibc-rh1027348-2.patch

00db10
commit ff8714269c9312d9164456279a56b6f6c47e2771
00db10
Author: Torvald Riegel <triegel@redhat.com>
00db10
Date:   Sun Sep 14 20:04:54 2014 +0200
00db10
00db10
    Add atomic operations similar to those provided by C11.
00db10
00db10
Index: glibc-2.17-c758a686/include/atomic.h
00db10
===================================================================
00db10
--- glibc-2.17-c758a686.orig/include/atomic.h
00db10
+++ glibc-2.17-c758a686/include/atomic.h
00db10
@@ -542,6 +542,218 @@
00db10
   ({ __typeof (x) __x; __asm ("" : "=r" (__x) : "0" (x)); __x; })
00db10
 #endif
00db10
 
00db10
+/* This is equal to 1 iff the architecture supports 64b atomic operations.  */
00db10
+#ifndef __HAVE_64B_ATOMICS
00db10
+#error Unable to determine if 64-bit atomics are present.
00db10
+#endif
00db10
+
00db10
+/* The following functions are a subset of the atomic operations provided by
00db10
+   C11.  Usually, a function named atomic_OP_MO(args) is equivalent to C11's
00db10
+   atomic_OP_explicit(args, memory_order_MO); exceptions noted below.  */
00db10
+
00db10
+/* Each arch can request to use compiler built-ins for C11 atomics.  If it
00db10
+   does, all atomics will be based on these.  */
00db10
+#if USE_ATOMIC_COMPILER_BUILTINS
00db10
+
00db10
+/* We require 32b atomic operations; some archs also support 64b atomic
00db10
+   operations.  */
00db10
+void __atomic_link_error (void);
00db10
+# if __HAVE_64B_ATOMICS == 1
00db10
+#  define __atomic_check_size(mem) \
00db10
+   if ((sizeof (*mem) != 4) && (sizeof (*mem) != 8))			      \
00db10
+     __atomic_link_error ();
00db10
+# else
00db10
+#  define __atomic_check_size(mem) \
00db10
+   if (sizeof (*mem) != 4)						      \
00db10
+     __atomic_link_error ();
00db10
+# endif
00db10
+
00db10
+# define atomic_thread_fence_acquire() \
00db10
+  __atomic_thread_fence (__ATOMIC_ACQUIRE)
00db10
+# define atomic_thread_fence_release() \
00db10
+  __atomic_thread_fence (__ATOMIC_RELEASE)
00db10
+# define atomic_thread_fence_seq_cst() \
00db10
+  __atomic_thread_fence (__ATOMIC_SEQ_CST)
00db10
+
00db10
+# define atomic_load_relaxed(mem) \
00db10
+  ({ __atomic_check_size((mem)); __atomic_load_n ((mem), __ATOMIC_RELAXED); })
00db10
+# define atomic_load_acquire(mem) \
00db10
+  ({ __atomic_check_size((mem)); __atomic_load_n ((mem), __ATOMIC_ACQUIRE); })
00db10
+
00db10
+# define atomic_store_relaxed(mem, val) \
00db10
+  do {									      \
00db10
+    __atomic_check_size((mem));						      \
00db10
+    __atomic_store_n ((mem), (val), __ATOMIC_RELAXED);			      \
00db10
+  } while (0)
00db10
+# define atomic_store_release(mem, val) \
00db10
+  do {									      \
00db10
+    __atomic_check_size((mem));						      \
00db10
+    __atomic_store_n ((mem), (val), __ATOMIC_RELEASE);			      \
00db10
+  } while (0)
00db10
+
00db10
+/* On failure, this CAS has memory_order_relaxed semantics.  */
00db10
+# define atomic_compare_exchange_weak_relaxed(mem, expected, desired) \
00db10
+  ({ __atomic_check_size((mem));					      \
00db10
+  __atomic_compare_exchange_n ((mem), (expected), (desired), 1,		      \
00db10
+    __ATOMIC_RELAXED, __ATOMIC_RELAXED); })
00db10
+# define atomic_compare_exchange_weak_acquire(mem, expected, desired) \
00db10
+  ({ __atomic_check_size((mem));					      \
00db10
+  __atomic_compare_exchange_n ((mem), (expected), (desired), 1,		      \
00db10
+    __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); })
00db10
+# define atomic_compare_exchange_weak_release(mem, expected, desired) \
00db10
+  ({ __atomic_check_size((mem));					      \
00db10
+  __atomic_compare_exchange_n ((mem), (expected), (desired), 1,		      \
00db10
+    __ATOMIC_RELEASE, __ATOMIC_RELAXED); })
00db10
+
00db10
+# define atomic_exchange_acquire(mem, desired) \
00db10
+  ({ __atomic_check_size((mem));					      \
00db10
+  __atomic_exchange_n ((mem), (desired), __ATOMIC_ACQUIRE); })
00db10
+# define atomic_exchange_release(mem, desired) \
00db10
+  ({ __atomic_check_size((mem));					      \
00db10
+  __atomic_exchange_n ((mem), (desired), __ATOMIC_RELEASE); })
00db10
+
00db10
+# define atomic_fetch_add_relaxed(mem, operand) \
00db10
+  ({ __atomic_check_size((mem));					      \
00db10
+  __atomic_fetch_add ((mem), (operand), __ATOMIC_RELAXED); })
00db10
+# define atomic_fetch_add_acquire(mem, operand) \
00db10
+  ({ __atomic_check_size((mem));					      \
00db10
+  __atomic_fetch_add ((mem), (operand), __ATOMIC_ACQUIRE); })
00db10
+# define atomic_fetch_add_release(mem, operand) \
00db10
+  ({ __atomic_check_size((mem));					      \
00db10
+  __atomic_fetch_add ((mem), (operand), __ATOMIC_RELEASE); })
00db10
+# define atomic_fetch_add_acq_rel(mem, operand) \
00db10
+  ({ __atomic_check_size((mem));					      \
00db10
+  __atomic_fetch_add ((mem), (operand), __ATOMIC_ACQ_REL); })
00db10
+
00db10
+# define atomic_fetch_and_acquire(mem, operand) \
00db10
+  ({ __atomic_check_size((mem));					      \
00db10
+  __atomic_fetch_and ((mem), (operand), __ATOMIC_ACQUIRE); })
00db10
+
00db10
+# define atomic_fetch_or_relaxed(mem, operand) \
00db10
+  ({ __atomic_check_size((mem));					      \
00db10
+  __atomic_fetch_or ((mem), (operand), __ATOMIC_RELAXED); })
00db10
+# define atomic_fetch_or_acquire(mem, operand) \
00db10
+  ({ __atomic_check_size((mem));					      \
00db10
+  __atomic_fetch_or ((mem), (operand), __ATOMIC_ACQUIRE); })
00db10
+
00db10
+#else /* !USE_ATOMIC_COMPILER_BUILTINS  */
00db10
+
00db10
+/* By default, we assume that read, write, and full barriers are equivalent
00db10
+   to acquire, release, and seq_cst barriers.  Archs for which this does not
00db10
+   hold have to provide custom definitions of the fences.  */
00db10
+# ifndef atomic_thread_fence_acquire
00db10
+#  define atomic_thread_fence_acquire() atomic_read_barrier ()
00db10
+# endif
00db10
+# ifndef atomic_thread_fence_release
00db10
+#  define atomic_thread_fence_release() atomic_write_barrier ()
00db10
+# endif
00db10
+# ifndef atomic_thread_fence_seq_cst
00db10
+#  define atomic_thread_fence_seq_cst() atomic_full_barrier ()
00db10
+# endif
00db10
+
00db10
+# ifndef atomic_load_relaxed
00db10
+#  define atomic_load_relaxed(mem) \
00db10
+   ({ __typeof (*(mem)) __atg100_val;					      \
00db10
+   __asm ("" : "=r" (__atg100_val) : "0" (*(mem)));			      \
00db10
+   __atg100_val; })
00db10
+# endif
00db10
+# ifndef atomic_load_acquire
00db10
+#  define atomic_load_acquire(mem) \
00db10
+   ({ __typeof (*(mem)) __atg101_val = atomic_load_relaxed (mem);	      \
00db10
+   atomic_thread_fence_acquire ();					      \
00db10
+   __atg101_val; })
00db10
+# endif
00db10
+
00db10
+# ifndef atomic_store_relaxed
00db10
+/* XXX Use inline asm here?  */
00db10
+#  define atomic_store_relaxed(mem, val) do { *(mem) = (val); } while (0)
00db10
+# endif
00db10
+# ifndef atomic_store_release
00db10
+#  define atomic_store_release(mem, val) \
00db10
+   do {									      \
00db10
+     atomic_thread_fence_release ();					      \
00db10
+     atomic_store_relaxed ((mem), (val));				      \
00db10
+   } while (0)
00db10
+# endif
00db10
+
00db10
+/* On failure, this CAS has memory_order_relaxed semantics.  */
00db10
+/* XXX This potentially has one branch more than necessary, but archs
00db10
+   currently do not define a CAS that returns both the previous value and
00db10
+   the success flag.  */
00db10
+# ifndef atomic_compare_exchange_weak_acquire
00db10
+#  define atomic_compare_exchange_weak_acquire(mem, expected, desired) \
00db10
+   ({ typeof (*(expected)) __atg102_expected = *(expected);		      \
00db10
+   *(expected) =							      \
00db10
+     atomic_compare_and_exchange_val_acq ((mem), (desired), *(expected));     \
00db10
+   *(expected) == __atg102_expected; })
00db10
+# endif
00db10
+# ifndef atomic_compare_exchange_weak_relaxed
00db10
+/* XXX Fall back to CAS with acquire MO because archs do not define a weaker
00db10
+   CAS.  */
00db10
+#  define atomic_compare_exchange_weak_relaxed(mem, expected, desired) \
00db10
+   atomic_compare_exchange_weak_acquire ((mem), (expected), (desired))
00db10
+# endif
00db10
+# ifndef atomic_compare_exchange_weak_release
00db10
+#  define atomic_compare_exchange_weak_release(mem, expected, desired) \
00db10
+   ({ typeof (*(expected)) __atg103_expected = *(expected);		      \
00db10
+   *(expected) =							      \
00db10
+     atomic_compare_and_exchange_val_rel ((mem), (desired), *(expected));     \
00db10
+   *(expected) == __atg103_expected; })
00db10
+# endif
00db10
+
00db10
+# ifndef atomic_exchange_acquire
00db10
+#  define atomic_exchange_acquire(mem, val) \
00db10
+   atomic_exchange_acq ((mem), (val))
00db10
+# endif
00db10
+# ifndef atomic_exchange_release
00db10
+#  define atomic_exchange_release(mem, val) \
00db10
+   atomic_exchange_rel ((mem), (val))
00db10
+# endif
00db10
+
00db10
+# ifndef atomic_fetch_add_acquire
00db10
+#  define atomic_fetch_add_acquire(mem, operand) \
00db10
+   atomic_exchange_and_add_acq ((mem), (operand))
00db10
+# endif
00db10
+# ifndef atomic_fetch_add_relaxed
00db10
+/* XXX Fall back to acquire MO because the MO semantics of
00db10
+   atomic_exchange_and_add are not documented; the generic version falls back
00db10
+   to atomic_exchange_and_add_acq if atomic_exchange_and_add is not defined,
00db10
+   and vice versa.  */
00db10
+#  define atomic_fetch_add_relaxed(mem, operand) \
00db10
+   atomic_fetch_add_acquire ((mem), (operand))
00db10
+# endif
00db10
+# ifndef atomic_fetch_add_release
00db10
+#  define atomic_fetch_add_release(mem, operand) \
00db10
+   atomic_exchange_and_add_rel ((mem), (operand))
00db10
+# endif
00db10
+# ifndef atomic_fetch_add_acq_rel
00db10
+#  define atomic_fetch_add_acq_rel(mem, operand) \
00db10
+   ({ atomic_thread_fence_release ();					      \
00db10
+   atomic_exchange_and_add_acq ((mem), (operand)); })
00db10
+# endif
00db10
+
00db10
+/* XXX The default for atomic_and_val has acquire semantics, but this is not
00db10
+   documented.  */
00db10
+# ifndef atomic_fetch_and_acquire
00db10
+#  define atomic_fetch_and_acquire(mem, operand) \
00db10
+   atomic_and_val ((mem), (operand))
00db10
+# endif
00db10
+
00db10
+/* XXX The default for atomic_or_val has acquire semantics, but this is not
00db10
+   documented.  */
00db10
+# ifndef atomic_fetch_or_acquire
00db10
+#  define atomic_fetch_or_acquire(mem, operand) \
00db10
+   atomic_or_val ((mem), (operand))
00db10
+# endif
00db10
+/* XXX Fall back to acquire MO because archs do not define a weaker
00db10
+   atomic_or_val.  */
00db10
+# ifndef atomic_fetch_or_relaxed
00db10
+#  define atomic_fetch_or_relaxed(mem, operand) \
00db10
+   atomic_fetch_or_acquire ((mem), (operand))
00db10
+# endif
00db10
+
00db10
+#endif /* !USE_ATOMIC_COMPILER_BUILTINS  */
00db10
+
00db10
 
00db10
 #ifndef atomic_delay
00db10
 # define atomic_delay() do { /* nothing */ } while (0)