Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8aaf1dda authored by Chris Metcalf's avatar Chris Metcalf
Browse files

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: default avatarChris Metcalf <cmetcalf@tilera.com>
parent 4800a5bb
Loading
Loading
Loading
Loading
+42 −7
Original line number Diff line number Diff line
@@ -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__ */
+0 −10
Original line number Diff line number Diff line
@@ -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 {
+2 −15
Original line number Diff line number Diff line
@@ -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__ */