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 <asm/atomic.h>, 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 <cmetcalf@tilera.com>
This commit is contained in:
Chris Metcalf 2011-05-16 13:59:39 -04:00
parent 4800a5bb13
commit 8aaf1dda42
3 changed files with 44 additions and 32 deletions

View File

@ -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__ */

View File

@ -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 {

View File

@ -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__ */