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:
parent
4800a5bb13
commit
8aaf1dda42
|
@ -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)
|
#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. */
|
/* Nonexistent functions intended to cause link errors. */
|
||||||
extern unsigned long __xchg_called_with_bad_pointer(void);
|
extern unsigned long __xchg_called_with_bad_pointer(void);
|
||||||
extern unsigned long __cmpxchg_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))
|
#define tas(ptr) (xchg((ptr), 1))
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
|
@ -110,16 +110,6 @@ static inline void atomic_set(atomic_t *v, int n)
|
||||||
_atomic_xchg(v, 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 */
|
/* A 64bit atomic type */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -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__before_atomic_inc() smp_mb()
|
||||||
#define smp_mb__after_atomic_inc() smp_mb()
|
#define smp_mb__after_atomic_inc() smp_mb()
|
||||||
|
|
||||||
#define xchg(ptr, x) \
|
/* Define this to indicate that cmpxchg is an efficient operation. */
|
||||||
((typeof(*(ptr))) \
|
#define __HAVE_ARCH_CMPXCHG
|
||||||
((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()))
|
|
||||||
|
|
||||||
#endif /* !__ASSEMBLY__ */
|
#endif /* !__ASSEMBLY__ */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue