aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2011-05-16 13:59:39 -0400
committerChris Metcalf <cmetcalf@tilera.com>2011-05-19 22:55:49 -0400
commit8aaf1dda42576b0f8dffb004065baa806f4df9b6 (patch)
treee9376caaf70b54e4b236840a1cc77a443c07b341 /arch
parent4800a5bb13c09a572f7c74662a77c9eca229eba1 (diff)
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/tile/include/asm/atomic.h49
-rw-r--r--arch/tile/include/asm/atomic_32.h10
-rw-r--r--arch/tile/include/asm/atomic_64.h17
3 files changed, 44 insertions, 32 deletions
diff --git a/arch/tile/include/asm/atomic.h b/arch/tile/include/asm/atomic.h
index 75a16028a952..739cfe0499d1 100644
--- a/arch/tile/include/asm/atomic.h
+++ b/arch/tile/include/asm/atomic.h
@@ -130,17 +130,52 @@ static inline int atomic_read(const atomic_t *v)
130 */ 130 */
131#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) 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/* Nonexistent functions intended to cause link errors. */ 133/* Nonexistent functions intended to cause link errors. */
141extern unsigned long __xchg_called_with_bad_pointer(void); 134extern unsigned long __xchg_called_with_bad_pointer(void);
142extern unsigned long __cmpxchg_called_with_bad_pointer(void); 135extern unsigned long __cmpxchg_called_with_bad_pointer(void);
143 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 })
178
144#define tas(ptr) (xchg((ptr), 1)) 179#define tas(ptr) (xchg((ptr), 1))
145 180
146#endif /* __ASSEMBLY__ */ 181#endif /* __ASSEMBLY__ */
diff --git a/arch/tile/include/asm/atomic_32.h b/arch/tile/include/asm/atomic_32.h
index ed359aee8837..92a8bee32311 100644
--- a/arch/tile/include/asm/atomic_32.h
+++ b/arch/tile/include/asm/atomic_32.h
@@ -110,16 +110,6 @@ static inline void atomic_set(atomic_t *v, int n)
110 _atomic_xchg(v, n); 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/* A 64bit atomic type */ 113/* A 64bit atomic type */
124 114
125typedef struct { 115typedef struct {
diff --git a/arch/tile/include/asm/atomic_64.h b/arch/tile/include/asm/atomic_64.h
index 321705294800..1c1e60d8ccb6 100644
--- a/arch/tile/include/asm/atomic_64.h
+++ b/arch/tile/include/asm/atomic_64.h
@@ -148,21 +148,8 @@ static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
148#define smp_mb__before_atomic_inc() smp_mb() 148#define smp_mb__before_atomic_inc() smp_mb()
149#define smp_mb__after_atomic_inc() smp_mb() 149#define smp_mb__after_atomic_inc() smp_mb()
150 150
151#define xchg(ptr, x) \ 151/* Define this to indicate that cmpxchg is an efficient operation. */
152 ((typeof(*(ptr))) \ 152#define __HAVE_ARCH_CMPXCHG
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()))
166 153
167#endif /* !__ASSEMBLY__ */ 154#endif /* !__ASSEMBLY__ */
168 155