From 8aaf1dda42576b0f8dffb004065baa806f4df9b6 Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Mon, 16 May 2011 13:59:39 -0400 Subject: [PATCH] arch/tile: use better definitions of xchg() and cmpxchg() These definitions use a ({}) construct to avoid some cases where we were getting warnings about unused return values. We also promote the definition to the common , since it applies to both the 32- and 64-bit atomics. In addition, define __HAVE_ARCH_CMPXCHG for TILE-Gx since it has efficient direct atomic instructions. Signed-off-by: Chris Metcalf --- arch/tile/include/asm/atomic.h | 49 ++++++++++++++++++++++++++----- arch/tile/include/asm/atomic_32.h | 10 ------- arch/tile/include/asm/atomic_64.h | 17 ++--------- 3 files changed, 44 insertions(+), 32 deletions(-) diff --git a/arch/tile/include/asm/atomic.h b/arch/tile/include/asm/atomic.h index 75a16028a952..739cfe0499d1 100644 --- a/arch/tile/include/asm/atomic.h +++ b/arch/tile/include/asm/atomic.h @@ -130,17 +130,52 @@ static inline int atomic_read(const atomic_t *v) */ #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) - -/* - * We define xchg() and cmpxchg() in the included headers. - * Note that we do not define __HAVE_ARCH_CMPXCHG, since that would imply - * that cmpxchg() is an efficient operation, which is not particularly true. - */ - /* Nonexistent functions intended to cause link errors. */ extern unsigned long __xchg_called_with_bad_pointer(void); extern unsigned long __cmpxchg_called_with_bad_pointer(void); +#define xchg(ptr, x) \ + ({ \ + typeof(*(ptr)) __x; \ + switch (sizeof(*(ptr))) { \ + case 4: \ + __x = (typeof(__x))(typeof(__x-__x))atomic_xchg( \ + (atomic_t *)(ptr), \ + (u32)(typeof((x)-(x)))(x)); \ + break; \ + case 8: \ + __x = (typeof(__x))(typeof(__x-__x))atomic64_xchg( \ + (atomic64_t *)(ptr), \ + (u64)(typeof((x)-(x)))(x)); \ + break; \ + default: \ + __xchg_called_with_bad_pointer(); \ + } \ + __x; \ + }) + +#define cmpxchg(ptr, o, n) \ + ({ \ + typeof(*(ptr)) __x; \ + switch (sizeof(*(ptr))) { \ + case 4: \ + __x = (typeof(__x))(typeof(__x-__x))atomic_cmpxchg( \ + (atomic_t *)(ptr), \ + (u32)(typeof((o)-(o)))(o), \ + (u32)(typeof((n)-(n)))(n)); \ + break; \ + case 8: \ + __x = (typeof(__x))(typeof(__x-__x))atomic64_cmpxchg( \ + (atomic64_t *)(ptr), \ + (u64)(typeof((o)-(o)))(o), \ + (u64)(typeof((n)-(n)))(n)); \ + break; \ + default: \ + __cmpxchg_called_with_bad_pointer(); \ + } \ + __x; \ + }) + #define tas(ptr) (xchg((ptr), 1)) #endif /* __ASSEMBLY__ */ diff --git a/arch/tile/include/asm/atomic_32.h b/arch/tile/include/asm/atomic_32.h index ed359aee8837..92a8bee32311 100644 --- a/arch/tile/include/asm/atomic_32.h +++ b/arch/tile/include/asm/atomic_32.h @@ -110,16 +110,6 @@ static inline void atomic_set(atomic_t *v, int n) _atomic_xchg(v, n); } -#define xchg(ptr, x) ((typeof(*(ptr))) \ - ((sizeof(*(ptr)) == sizeof(atomic_t)) ? \ - atomic_xchg((atomic_t *)(ptr), (long)(x)) : \ - __xchg_called_with_bad_pointer())) - -#define cmpxchg(ptr, o, n) ((typeof(*(ptr))) \ - ((sizeof(*(ptr)) == sizeof(atomic_t)) ? \ - atomic_cmpxchg((atomic_t *)(ptr), (long)(o), (long)(n)) : \ - __cmpxchg_called_with_bad_pointer())) - /* A 64bit atomic type */ typedef struct { diff --git a/arch/tile/include/asm/atomic_64.h b/arch/tile/include/asm/atomic_64.h index 321705294800..1c1e60d8ccb6 100644 --- a/arch/tile/include/asm/atomic_64.h +++ b/arch/tile/include/asm/atomic_64.h @@ -148,21 +148,8 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u) #define smp_mb__before_atomic_inc() smp_mb() #define smp_mb__after_atomic_inc() smp_mb() -#define xchg(ptr, x) \ - ((typeof(*(ptr))) \ - ((sizeof(*(ptr)) == sizeof(atomic_t)) ? \ - atomic_xchg((atomic_t *)(ptr), (long)(x)) : \ - (sizeof(*(ptr)) == sizeof(atomic_long_t)) ? \ - atomic_long_xchg((atomic_long_t *)(ptr), (long)(x)) : \ - __xchg_called_with_bad_pointer())) - -#define cmpxchg(ptr, o, n) \ - ((typeof(*(ptr))) \ - ((sizeof(*(ptr)) == sizeof(atomic_t)) ? \ - atomic_cmpxchg((atomic_t *)(ptr), (long)(o), (long)(n)) : \ - (sizeof(*(ptr)) == sizeof(atomic_long_t)) ? \ - atomic_long_cmpxchg((atomic_long_t *)(ptr), (long)(o), (long)(n)) : \ - __cmpxchg_called_with_bad_pointer())) +/* Define this to indicate that cmpxchg is an efficient operation. */ +#define __HAVE_ARCH_CMPXCHG #endif /* !__ASSEMBLY__ */