diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2011-05-16 13:59:39 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2011-05-19 22:55:49 -0400 |
commit | 8aaf1dda42576b0f8dffb004065baa806f4df9b6 (patch) | |
tree | e9376caaf70b54e4b236840a1cc77a443c07b341 /arch | |
parent | 4800a5bb13c09a572f7c74662a77c9eca229eba1 (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.h | 49 | ||||
-rw-r--r-- | arch/tile/include/asm/atomic_32.h | 10 | ||||
-rw-r--r-- | arch/tile/include/asm/atomic_64.h | 17 |
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. */ |
141 | extern unsigned long __xchg_called_with_bad_pointer(void); | 134 | extern unsigned long __xchg_called_with_bad_pointer(void); |
142 | extern unsigned long __cmpxchg_called_with_bad_pointer(void); | 135 | extern 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 | ||
125 | typedef struct { | 115 | typedef 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 | ||