summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/arc
diff options
context:
space:
mode:
authorVineet Gupta <Vineet.Gupta1@synopsys.com>2016-11-07 16:31:38 -0800
committerWaldemar Brodkorb <wbx@uclibc-ng.org>2016-11-13 13:44:35 +0100
commit0ef881ce9568e1c2e98351fdc067bebbc8c4696a (patch)
tree40d30d60a00e117852f5cf39afdf470323f9fe1e /libc/sysdeps/linux/arc
parentf6cfc2129c6902410619f6cba56022af2977b6a3 (diff)
NPTL/ARC: implement __arch_exchange_32_acq using native EX
ARC EX instruction maps directly to this primitive, thus helps elide the llock/scond based retry loop where possible. Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Diffstat (limited to 'libc/sysdeps/linux/arc')
-rw-r--r--libc/sysdeps/linux/arc/bits/atomic.h24
1 files changed, 24 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/arc/bits/atomic.h b/libc/sysdeps/linux/arc/bits/atomic.h
index 1fdc83f70..48f37879c 100644
--- a/libc/sysdeps/linux/arc/bits/atomic.h
+++ b/libc/sysdeps/linux/arc/bits/atomic.h
@@ -58,3 +58,27 @@ void __arc_link_error (void);
#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
({ __arc_link_error (); oldval; })
+
+/* Store NEWVALUE in *MEM and return the old value.
+ Atomic EX is present in all configurations
+ */
+
+#define __arch_exchange_32_acq(mem, newval) \
+ ({ \
+ __typeof__(*(mem)) val = newval; \
+ \
+ __asm__ __volatile__( \
+ "ex %0, [%1]" \
+ : "+r" (val) \
+ : "r" (mem) \
+ : "memory" ); \
+ \
+ val; \
+ })
+
+#define atomic_exchange_acq(mem, newval) \
+ ({ \
+ if (sizeof(*(mem)) != 4) \
+ abort(); \
+ __arch_exchange_32_acq(mem, newval); \
+ })