Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+44 -32
+42 -7
arch/tile/include/asm/atomic.h
··· 130 130 */ 131 131 #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) 132 132 133 - 134 - /* 135 - * We define xchg() and cmpxchg() in the included headers. 136 - * Note that we do not define __HAVE_ARCH_CMPXCHG, since that would imply 137 - * that cmpxchg() is an efficient operation, which is not particularly true. 138 - */ 139 - 140 133 /* Nonexistent functions intended to cause link errors. */ 141 134 extern unsigned long __xchg_called_with_bad_pointer(void); 142 135 extern unsigned long __cmpxchg_called_with_bad_pointer(void); 136 + 137 + #define xchg(ptr, x) \ 138 + ({ \ 139 + typeof(*(ptr)) __x; \ 140 + switch (sizeof(*(ptr))) { \ 141 + case 4: \ 142 + __x = (typeof(__x))(typeof(__x-__x))atomic_xchg( \ 143 + (atomic_t *)(ptr), \ 144 + (u32)(typeof((x)-(x)))(x)); \ 145 + break; \ 146 + case 8: \ 147 + __x = (typeof(__x))(typeof(__x-__x))atomic64_xchg( \ 148 + (atomic64_t *)(ptr), \ 149 + (u64)(typeof((x)-(x)))(x)); \ 150 + break; \ 151 + default: \ 152 + __xchg_called_with_bad_pointer(); \ 153 + } \ 154 + __x; \ 155 + }) 156 + 157 + #define cmpxchg(ptr, o, n) \ 158 + ({ \ 159 + typeof(*(ptr)) __x; \ 160 + switch (sizeof(*(ptr))) { \ 161 + case 4: \ 162 + __x = (typeof(__x))(typeof(__x-__x))atomic_cmpxchg( \ 163 + (atomic_t *)(ptr), \ 164 + (u32)(typeof((o)-(o)))(o), \ 165 + (u32)(typeof((n)-(n)))(n)); \ 166 + break; \ 167 + case 8: \ 168 + __x = (typeof(__x))(typeof(__x-__x))atomic64_cmpxchg( \ 169 + (atomic64_t *)(ptr), \ 170 + (u64)(typeof((o)-(o)))(o), \ 171 + (u64)(typeof((n)-(n)))(n)); \ 172 + break; \ 173 + default: \ 174 + __cmpxchg_called_with_bad_pointer(); \ 175 + } \ 176 + __x; \ 177 + }) 143 178 144 179 #define tas(ptr) (xchg((ptr), 1)) 145 180
-10
arch/tile/include/asm/atomic_32.h
··· 110 110 _atomic_xchg(v, n); 111 111 } 112 112 113 - #define xchg(ptr, x) ((typeof(*(ptr))) \ 114 - ((sizeof(*(ptr)) == sizeof(atomic_t)) ? \ 115 - atomic_xchg((atomic_t *)(ptr), (long)(x)) : \ 116 - __xchg_called_with_bad_pointer())) 117 - 118 - #define cmpxchg(ptr, o, n) ((typeof(*(ptr))) \ 119 - ((sizeof(*(ptr)) == sizeof(atomic_t)) ? \ 120 - atomic_cmpxchg((atomic_t *)(ptr), (long)(o), (long)(n)) : \ 121 - __cmpxchg_called_with_bad_pointer())) 122 - 123 113 /* A 64bit atomic type */ 124 114 125 115 typedef struct {
+2 -15
arch/tile/include/asm/atomic_64.h
··· 148 148 #define smp_mb__before_atomic_inc() smp_mb() 149 149 #define smp_mb__after_atomic_inc() smp_mb() 150 150 151 - #define xchg(ptr, x) \ 152 - ((typeof(*(ptr))) \ 153 - ((sizeof(*(ptr)) == sizeof(atomic_t)) ? \ 154 - atomic_xchg((atomic_t *)(ptr), (long)(x)) : \ 155 - (sizeof(*(ptr)) == sizeof(atomic_long_t)) ? \ 156 - atomic_long_xchg((atomic_long_t *)(ptr), (long)(x)) : \ 157 - __xchg_called_with_bad_pointer())) 158 - 159 - #define cmpxchg(ptr, o, n) \ 160 - ((typeof(*(ptr))) \ 161 - ((sizeof(*(ptr)) == sizeof(atomic_t)) ? \ 162 - atomic_cmpxchg((atomic_t *)(ptr), (long)(o), (long)(n)) : \ 163 - (sizeof(*(ptr)) == sizeof(atomic_long_t)) ? \ 164 - atomic_long_cmpxchg((atomic_long_t *)(ptr), (long)(o), (long)(n)) : \ 165 - __cmpxchg_called_with_bad_pointer())) 151 + /* Define this to indicate that cmpxchg is an efficient operation. */ 152 + #define __HAVE_ARCH_CMPXCHG 166 153 167 154 #endif /* !__ASSEMBLY__ */ 168 155