diff options
Diffstat (limited to 'arch/powerpc/include/asm/atomic.h')
-rw-r--r-- | arch/powerpc/include/asm/atomic.h | 67 |
1 files changed, 60 insertions, 7 deletions
diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h index 02e41b53488d..da29032ae38f 100644 --- a/arch/powerpc/include/asm/atomic.h +++ b/arch/powerpc/include/asm/atomic.h @@ -5,13 +5,9 @@ * PowerPC atomic operations */ -#include <linux/types.h> - #ifdef __KERNEL__ -#include <linux/compiler.h> -#include <asm/synch.h> -#include <asm/asm-compat.h> -#include <asm/system.h> +#include <linux/types.h> +#include <asm/cmpxchg.h> #define ATOMIC_INIT(i) { (i) } @@ -212,6 +208,36 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) return t; } +/** + * atomic_inc_not_zero - increment unless the number is zero + * @v: pointer of type atomic_t + * + * Atomically increments @v by 1, so long as @v is non-zero. + * Returns non-zero if @v was non-zero, and zero otherwise. + */ +static __inline__ int atomic_inc_not_zero(atomic_t *v) +{ + int t1, t2; + + __asm__ __volatile__ ( + PPC_ATOMIC_ENTRY_BARRIER +"1: lwarx %0,0,%2 # atomic_inc_not_zero\n\ + cmpwi 0,%0,0\n\ + beq- 2f\n\ + addic %1,%0,1\n" + PPC405_ERR77(0,%2) +" stwcx. %1,0,%2\n\ + bne- 1b\n" + PPC_ATOMIC_EXIT_BARRIER + "\n\ +2:" + : "=&r" (t1), "=&r" (t2) + : "r" (&v->counter) + : "cc", "xer", "memory"); + + return t1; +} +#define atomic_inc_not_zero(v) atomic_inc_not_zero((v)) #define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0) #define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0) @@ -467,7 +493,34 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) return t != u; } -#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) +/** + * atomic_inc64_not_zero - increment unless the number is zero + * @v: pointer of type atomic64_t + * + * Atomically increments @v by 1, so long as @v is non-zero. + * Returns non-zero if @v was non-zero, and zero otherwise. + */ +static __inline__ long atomic64_inc_not_zero(atomic64_t *v) +{ + long t1, t2; + + __asm__ __volatile__ ( + PPC_ATOMIC_ENTRY_BARRIER +"1: ldarx %0,0,%2 # atomic64_inc_not_zero\n\ + cmpdi 0,%0,0\n\ + beq- 2f\n\ + addic %1,%0,1\n\ + stdcx. %1,0,%2\n\ + bne- 1b\n" + PPC_ATOMIC_EXIT_BARRIER + "\n\ +2:" + : "=&r" (t1), "=&r" (t2) + : "r" (&v->counter) + : "cc", "xer", "memory"); + + return t1; +} #endif /* __powerpc64__ */ |