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:
Родитель
4800a5bb13
Коммит
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)
|
||||
|
||||
|
||||
/*
|
||||
* 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__ */
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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__ */
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче