summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-01-23 11:27:24 -0800
committerDavid S. Miller <davem@davemloft.net>2013-01-23 11:27:24 -0800
commitbae8e7f5ed0cdc8a81ae9b32efc77285d2f5bc7a (patch)
treeb2deb8c9c341212727f5c04750c5cc6401635698
parent67b3f58c83d4ffc29ab939e3d0bbeb9fb38103e7 (diff)
Add a minor 'cas' atomic optimization on sparc.
* sysdeps/sparc/sparc32/sparcv9/bits/atomic.h (__arch_compare_and_exchange_val_32_acq): Use %g0 as second argument of CAS if possible. * sysdeps/sparc/sparc64/bits/atomic.h (__arch_compare_and_exchange_val_32_acq): Likewise. (__arch_compare_and_exchange_val_64_acq): Likewise.
-rw-r--r--ChangeLog9
-rw-r--r--sysdeps/sparc/sparc32/sparcv9/bits/atomic.h14
-rw-r--r--sysdeps/sparc/sparc64/bits/atomic.h28
3 files changed, 39 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index 418b9320d1..00f702735e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2013-01-23 David S. Miller <davem@davemloft.net>
+
+ * sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
+ (__arch_compare_and_exchange_val_32_acq): Use %g0 as second
+ argument of CAS if possible.
+ * sysdeps/sparc/sparc64/bits/atomic.h
+ (__arch_compare_and_exchange_val_32_acq): Likewise.
+ (__arch_compare_and_exchange_val_64_acq): Likewise.
+
2013-01-23 Pino Toscano <toscano.pino@tiscali.it>
* sysdeps/unix/sysv/linux/ulimit.c: Moved to ...
diff --git a/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h b/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
index b1a89584f6..937d7a149f 100644
--- a/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
+++ b/sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
@@ -55,10 +55,16 @@ typedef uintmax_t uatomic_max_t;
({ \
__typeof (*(mem)) __acev_tmp; \
__typeof (mem) __acev_mem = (mem); \
- __asm __volatile ("cas [%4], %2, %0" \
- : "=r" (__acev_tmp), "=m" (*__acev_mem) \
- : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \
- "0" (newval) : "memory"); \
+ if (__builtin_constant_p (oldval) && (oldval) == 0) \
+ __asm __volatile ("cas [%3], %%g0, %0" \
+ : "=r" (__acev_tmp), "=m" (*__acev_mem) \
+ : "m" (*__acev_mem), "r" (__acev_mem), \
+ "0" (newval) : "memory"); \
+ else \
+ __asm __volatile ("cas [%4], %2, %0" \
+ : "=r" (__acev_tmp), "=m" (*__acev_mem) \
+ : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \
+ "0" (newval) : "memory"); \
__acev_tmp; })
/* This can be implemented if needed. */
diff --git a/sysdeps/sparc/sparc64/bits/atomic.h b/sysdeps/sparc/sparc64/bits/atomic.h
index 0afbb4ba5e..96611de42f 100644
--- a/sysdeps/sparc/sparc64/bits/atomic.h
+++ b/sysdeps/sparc/sparc64/bits/atomic.h
@@ -55,20 +55,32 @@ typedef uintmax_t uatomic_max_t;
({ \
__typeof (*(mem)) __acev_tmp; \
__typeof (mem) __acev_mem = (mem); \
- __asm __volatile ("cas [%4], %2, %0" \
- : "=r" (__acev_tmp), "=m" (*__acev_mem) \
- : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \
- "0" (newval) : "memory"); \
+ if (__builtin_constant_p (oldval) && (oldval) == 0) \
+ __asm __volatile ("cas [%3], %%g0, %0" \
+ : "=r" (__acev_tmp), "=m" (*__acev_mem) \
+ : "m" (*__acev_mem), "r" (__acev_mem), \
+ "0" (newval) : "memory"); \
+ else \
+ __asm __volatile ("cas [%4], %2, %0" \
+ : "=r" (__acev_tmp), "=m" (*__acev_mem) \
+ : "r" (oldval), "m" (*__acev_mem), "r" (__acev_mem), \
+ "0" (newval) : "memory"); \
__acev_tmp; })
#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
({ \
__typeof (*(mem)) __acev_tmp; \
__typeof (mem) __acev_mem = (mem); \
- __asm __volatile ("casx [%4], %2, %0" \
- : "=r" (__acev_tmp), "=m" (*__acev_mem) \
- : "r" ((long) (oldval)), "m" (*__acev_mem), \
- "r" (__acev_mem), "0" ((long) (newval)) : "memory"); \
+ if (__builtin_constant_p (oldval) && (oldval) == 0) \
+ __asm __volatile ("casx [%3], %%g0, %0" \
+ : "=r" (__acev_tmp), "=m" (*__acev_mem) \
+ : "m" (*__acev_mem), "r" (__acev_mem), \
+ "0" ((long) (newval)) : "memory"); \
+ else \
+ __asm __volatile ("casx [%4], %2, %0" \
+ : "=r" (__acev_tmp), "=m" (*__acev_mem) \
+ : "r" ((long) (oldval)), "m" (*__acev_mem), \
+ "r" (__acev_mem), "0" ((long) (newval)) : "memory"); \
__acev_tmp; })
#define atomic_exchange_acq(mem, newvalue) \