@@ -52,84 +52,184 @@ void __arm_link_error (void);
a pattern to do this efficiently. */
#if __GNUC_PREREQ (4, 7) && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
-# define atomic_exchange_acq(mem, value) \
- __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE)
+/* Compare and exchange.
+ For all "bool" routines, we return FALSE if exchange successful. */
-# define atomic_exchange_rel(mem, value) \
- __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE)
+# define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \
+ ({ \
+ typeof (*mem) __oldval = (oldval); \
+ !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
+ model, __ATOMIC_RELAXED); \
+ })
-/* Atomic exchange (without compare). */
+# define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \
+ ({ \
+ typeof (*mem) __oldval = (oldval); \
+ !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
+ model, __ATOMIC_RELAXED); \
+ })
-# define __arch_exchange_8_int(mem, newval, model) \
- (__arm_link_error (), (typeof (*mem)) 0)
+# define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \
+ ({ \
+ typeof (*mem) __oldval = (oldval); \
+ !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
+ model, __ATOMIC_RELAXED); \
+ })
-# define __arch_exchange_16_int(mem, newval, model) \
- (__arm_link_error (), (typeof (*mem)) 0)
+# define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \
+ ({ \
+ typeof (*mem) __oldval = (oldval); \
+ !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
+ model, __ATOMIC_RELAXED); \
+ })
-# define __arch_exchange_32_int(mem, newval, model) \
- __atomic_exchange_n (mem, newval, model)
+# define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \
+ ({ \
+ typeof (*mem) __oldval = (oldval); \
+ __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
+ model, __ATOMIC_RELAXED); \
+ __oldval; \
+ })
+
+# define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \
+ ({ \
+ typeof (*mem) __oldval = (oldval); \
+ __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
+ model, __ATOMIC_RELAXED); \
+ __oldval; \
+ })
+
+# define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \
+ ({ \
+ typeof (*mem) __oldval = (oldval); \
+ __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
+ model, __ATOMIC_RELAXED); \
+ __oldval; \
+ })
+
+# define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \
+ ({ \
+ typeof (*mem) __oldval = (oldval); \
+ __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
+ model, __ATOMIC_RELAXED); \
+ __oldval; \
+ })
-# define __arch_exchange_64_int(mem, newval, model) \
- (__arm_link_error (), (typeof (*mem)) 0)
/* Compare and exchange with "acquire" semantics, ie barrier after. */
-# define atomic_compare_and_exchange_bool_acq(mem, new, old) \
- __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
- mem, new, old, __ATOMIC_ACQUIRE)
+# define atomic_compare_and_exchange_bool_acq(mem, new, old) \
+ __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
+ mem, new, old, __ATOMIC_ACQUIRE)
-# define atomic_compare_and_exchange_val_acq(mem, new, old) \
- __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
- mem, new, old, __ATOMIC_ACQUIRE)
+# define atomic_compare_and_exchange_val_acq(mem, new, old) \
+ __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
+ mem, new, old, __ATOMIC_ACQUIRE)
/* Compare and exchange with "release" semantics, ie barrier before. */
-# define atomic_compare_and_exchange_bool_rel(mem, new, old) \
- __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
- mem, new, old, __ATOMIC_RELEASE)
+# define atomic_compare_and_exchange_bool_rel(mem, new, old) \
+ __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
+ mem, new, old, __ATOMIC_RELEASE)
-# define atomic_compare_and_exchange_val_rel(mem, new, old) \
+# define atomic_compare_and_exchange_val_rel(mem, new, old) \
__atomic_val_bysize (__arch_compare_and_exchange_val, int, \
mem, new, old, __ATOMIC_RELEASE)
-/* Compare and exchange.
- For all "bool" routines, we return FALSE if exchange succesful. */
-# define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \
- ({__arm_link_error (); 0; })
+/* Atomic exchange (without compare). */
-# define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \
- ({__arm_link_error (); 0; })
+# define __arch_exchange_8_int(mem, newval, model) \
+ __atomic_exchange_n (mem, newval, model)
-# define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \
- ({ \
- typeof (*mem) __oldval = (oldval); \
- !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
- model, __ATOMIC_RELAXED); \
- })
+# define __arch_exchange_16_int(mem, newval, model) \
+ __atomic_exchange_n (mem, newval, model)
-# define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \
- ({__arm_link_error (); 0; })
+# define __arch_exchange_32_int(mem, newval, model) \
+ __atomic_exchange_n (mem, newval, model)
-# define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \
- ({__arm_link_error (); oldval; })
+# define __arch_exchange_64_int(mem, newval, model) \
+ __atomic_exchange_n (mem, newval, model)
-# define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \
- ({__arm_link_error (); oldval; })
+# define atomic_exchange_acq(mem, value) \
+ __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE)
-# define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \
- ({ \
- typeof (*mem) __oldval = (oldval); \
- __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
- model, __ATOMIC_RELAXED); \
- __oldval; \
- })
+# define atomic_exchange_rel(mem, value) \
+ __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE)
+
+
+/* Atomically add value and return the previous (unincremented) value. */
+
+# define __arch_exchange_and_add_8_int(mem, value, model) \
+ __atomic_fetch_add (mem, value, model)
+
+# define __arch_exchange_and_add_16_int(mem, value, model) \
+ __atomic_fetch_add (mem, value, model)
+
+# define __arch_exchange_and_add_32_int(mem, value, model) \
+ __atomic_fetch_add (mem, value, model)
+
+# define __arch_exchange_and_add_64_int(mem, value, model) \
+ __atomic_fetch_add (mem, value, model)
+
+# define atomic_exchange_and_add_acq(mem, value) \
+ __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \
+ __ATOMIC_ACQUIRE)
+
+# define atomic_exchange_and_add_rel(mem, value) \
+ __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \
+ __ATOMIC_RELEASE)
+
+# define catomic_exchange_and_add atomic_exchange_and_add
+
+/* Atomically bitwise and value and return the previous value. */
+
+# define __arch_exchange_and_and_8_int(mem, value, model) \
+ __atomic_fetch_and (mem, value, model)
+
+# define __arch_exchange_and_and_16_int(mem, value, model) \
+ __atomic_fetch_and (mem, value, model)
-# define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \
- ({__arm_link_error (); oldval; })
+# define __arch_exchange_and_and_32_int(mem, value, model) \
+ __atomic_fetch_and (mem, value, model)
+
+# define __arch_exchange_and_and_64_int(mem, value, model) \
+ __atomic_fetch_and (mem, value, model)
+
+# define atomic_and(mem, value) \
+ __atomic_val_bysize (__arch_exchange_and_and, int, mem, value, \
+ __ATOMIC_ACQUIRE)
+
+# define atomic_and_val atomic_and
+
+# define catomic_and atomic_and
+
+/* Atomically bitwise or value and return the previous value. */
+
+# define __arch_exchange_and_or_8_int(mem, value, model) \
+ __atomic_fetch_or (mem, value, model)
+
+# define __arch_exchange_and_or_16_int(mem, value, model) \
+ __atomic_fetch_or (mem, value, model)
+
+# define __arch_exchange_and_or_32_int(mem, value, model) \
+ __atomic_fetch_or (mem, value, model)
+
+# define __arch_exchange_and_or_64_int(mem, value, model) \
+ __atomic_fetch_or (mem, value, model)
+
+# define atomic_or(mem, value) \
+ __atomic_val_bysize (__arch_exchange_and_or, int, mem, value, \
+ __ATOMIC_ACQUIRE)
+
+# define atomic_or_val atomic_or
+
+# define catomic_or atomic_or
#elif defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+
/* Atomic compare and exchange. */
+
# define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
__sync_val_compare_and_swap ((mem), (oldval), (newval))
#else
@@ -138,8 +238,10 @@ void __arm_link_error (void);
#endif
#if !__GNUC_PREREQ (4, 7) || !defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+
/* We don't support atomic operations on any non-word types.
So make them link errors. */
+
# define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
({ __arm_link_error (); oldval; })
@@ -148,6 +250,7 @@ void __arm_link_error (void);
# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
({ __arm_link_error (); oldval; })
+
#endif
/* An OS-specific bits/atomic.h file will define this macro if