aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2013-07-11 11:04:20 -0400
committerMatt Turner <mattst88@gmail.com>2013-07-19 16:54:24 -0400
commit748a76b5152e8f38edf8afbf6f4cd6e326ad9e62 (patch)
treed9df502d39bb7d2c8a689de740b32fb10be14f58 /arch
parent6da7539734d4e0f5caeea1e0efbb74d7b83db1ca (diff)
alpha: Implement atomic64_dec_if_positive
Reviewed-and-Tested-by: Matt Turner <mattst88@gmail.com> Signed-off-by: Matt Turner <mattst88@gmail.com> Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/Kconfig1
-rw-r--r--arch/alpha/include/asm/atomic.h28
2 files changed, 29 insertions, 0 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 837a1f2d8b96..082d9b4b5472 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -15,6 +15,7 @@ config ALPHA
15 select ARCH_WANT_OPTIONAL_GPIOLIB 15 select ARCH_WANT_OPTIONAL_GPIOLIB
16 select ARCH_WANT_IPC_PARSE_VERSION 16 select ARCH_WANT_IPC_PARSE_VERSION
17 select ARCH_HAVE_NMI_SAFE_CMPXCHG 17 select ARCH_HAVE_NMI_SAFE_CMPXCHG
18 select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
18 select GENERIC_SMP_IDLE_THREAD 19 select GENERIC_SMP_IDLE_THREAD
19 select GENERIC_CMOS_UPDATE 20 select GENERIC_CMOS_UPDATE
20 select GENERIC_STRNCPY_FROM_USER 21 select GENERIC_STRNCPY_FROM_USER
diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h
index 0dc18fc4d925..78b03ef39f6f 100644
--- a/arch/alpha/include/asm/atomic.h
+++ b/arch/alpha/include/asm/atomic.h
@@ -238,6 +238,34 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
238 return !c; 238 return !c;
239} 239}
240 240
241/*
242 * atomic64_dec_if_positive - decrement by 1 if old value positive
243 * @v: pointer of type atomic_t
244 *
245 * The function returns the old value of *v minus 1, even if
246 * the atomic variable, v, was not decremented.
247 */
248static inline long atomic64_dec_if_positive(atomic64_t *v)
249{
250 long old, tmp;
251 smp_mb();
252 __asm__ __volatile__(
253 "1: ldq_l %[old],%[mem]\n"
254 " subq %[old],1,%[tmp]\n"
255 " ble %[old],2f\n"
256 " stq_c %[tmp],%[mem]\n"
257 " beq %[tmp],3f\n"
258 "2:\n"
259 ".subsection 2\n"
260 "3: br 1b\n"
261 ".previous"
262 : [old] "=&r"(old), [tmp] "=&r"(tmp)
263 : [mem] "m"(*v)
264 : "memory");
265 smp_mb();
266 return old - 1;
267}
268
241#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) 269#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
242 270
243#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) 271#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)