[PATCH 02/10] local_t : alpha extension
local_t : alpha extension Signed-off-by: Mathieu Desnoyers <[EMAIL PROTECTED]> --- a/include/asm-alpha/local.h +++ b/include/asm-alpha/local.h @@ -4,37 +4,115 @@ #include #include -typedef atomic64_t local_t; +typedef struct +{ + atomic_long_t a; +} local_t; -#define LOCAL_INIT(i) ATOMIC64_INIT(i) -#define local_read(v) atomic64_read(v) -#define local_set(v,i) atomic64_set(v,i) +#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } +#define local_read(l) atomic_long_read(&(l)->a) +#define local_set(l,i) atomic_long_set(&(l)->a, (i)) +#define local_inc(l) atomic_long_inc(&(l)->a) +#define local_dec(l) atomic_long_dec(&(l)->a) +#define local_add(i,l) atomic_long_add((i),(&(l)->a)) +#define local_sub(i,l) atomic_long_sub((i),(&(l)->a)) -#define local_inc(v) atomic64_inc(v) -#define local_dec(v) atomic64_dec(v) -#define local_add(i, v)atomic64_add(i, v) -#define local_sub(i, v)atomic64_sub(i, v) +static __inline__ long local_add_return(long i, local_t * l) +{ + long temp, result; + __asm__ __volatile__( + "1: ldq_l %0,%1\n" + " addq %0,%3,%2\n" + " addq %0,%3,%0\n" + " stq_c %0,%1\n" + " beq %0,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + :"=" (temp), "=m" (l->a.counter), "=" (result) + :"Ir" (i), "m" (l->a.counter) : "memory"); + return result; +} -#define __local_inc(v) ((v)->counter++) -#define __local_dec(v) ((v)->counter++) -#define __local_add(i,v) ((v)->counter+=(i)) -#define __local_sub(i,v) ((v)->counter-=(i)) +static __inline__ long local_sub_return(long i, local_t * l) +{ + long temp, result; + __asm__ __volatile__( + "1: ldq_l %0,%1\n" + " subq %0,%3,%2\n" + " subq %0,%3,%0\n" + " stq_c %0,%1\n" + " beq %0,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + :"=" (temp), "=m" (l->a.counter), "=" (result) + :"Ir" (i), "m" (l->a.counter) : "memory"); + return result; +} + +#define local_cmpxchg(l, o, n) \ + (cmpxchg_local(&((l)->a.counter), (o), (n))) +#define local_xchg(l, n) (xchg_local(&((l)->a.counter), (n))) + +/** + * local_add_unless - add unless the number is a given value + * @l: pointer of type local_t + * @a: the amount to add to l... + * @u: ...unless l is equal to u. + * + * Atomically adds @a to @l, so long as it was not @u. + * Returns non-zero if @l was not @u, and zero otherwise. + */ +#define local_add_unless(l, a, u) \ +({ \ + long c, old;\ + c = local_read(l); \ + for (;;) { \ + if (unlikely(c == (u))) \ + break; \ + old = local_cmpxchg((l), c, c + (a)); \ + if (likely(old == c)) \ + break; \ + c = old;\ + } \ + c != (u); \ +}) +#define local_inc_not_zero(l) local_add_unless((l), 1, 0) + +#define local_add_negative(a, l) (local_add_return((a), (l)) < 0) + +#define local_dec_return(l) local_sub_return(1,(l)) + +#define local_inc_return(l) local_add_return(1,(l)) + +#define local_sub_and_test(i,l) (local_sub_return((i), (l)) == 0) + +#define local_inc_and_test(l) (local_add_return(1, (l)) == 0) + +#define local_dec_and_test(l) (local_sub_return(1, (l)) == 0) + +/* Verify if faster than atomic ops */ +#define __local_inc(l) ((l)->a.counter++) +#define __local_dec(l) ((l)->a.counter++) +#define __local_add(i,l) ((l)->a.counter+=(i)) +#define __local_sub(i,l) ((l)->a.counter-=(i)) /* Use these for per-cpu local_t variables: on some archs they are * much more efficient than these naive implementations. Note they take * a variable, not an address. */ -#define cpu_local_read(v) local_read(&__get_cpu_var(v)) -#define cpu_local_set(v, i)local_set(&__get_cpu_var(v), (i)) - -#define cpu_local_inc(v) local_inc(&__get_cpu_var(v)) -#define cpu_local_dec(v) local_dec(&__get_cpu_var(v)) -#define cpu_local_add(i, v)local_add((i), &__get_cpu_var(v)) -#define cpu_local_sub(i, v)local_sub((i), &__get_cpu_var(v)) - -#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v)) -#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v)) -#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v)) -#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v)) +#define cpu_local_read(l) local_read(&__get_cpu_var(l))
[PATCH 02/10] local_t : alpha extension
local_t : alpha extension Signed-off-by: Mathieu Desnoyers [EMAIL PROTECTED] --- a/include/asm-alpha/local.h +++ b/include/asm-alpha/local.h @@ -4,37 +4,115 @@ #include linux/percpu.h #include asm/atomic.h -typedef atomic64_t local_t; +typedef struct +{ + atomic_long_t a; +} local_t; -#define LOCAL_INIT(i) ATOMIC64_INIT(i) -#define local_read(v) atomic64_read(v) -#define local_set(v,i) atomic64_set(v,i) +#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } +#define local_read(l) atomic_long_read((l)-a) +#define local_set(l,i) atomic_long_set((l)-a, (i)) +#define local_inc(l) atomic_long_inc((l)-a) +#define local_dec(l) atomic_long_dec((l)-a) +#define local_add(i,l) atomic_long_add((i),((l)-a)) +#define local_sub(i,l) atomic_long_sub((i),((l)-a)) -#define local_inc(v) atomic64_inc(v) -#define local_dec(v) atomic64_dec(v) -#define local_add(i, v)atomic64_add(i, v) -#define local_sub(i, v)atomic64_sub(i, v) +static __inline__ long local_add_return(long i, local_t * l) +{ + long temp, result; + __asm__ __volatile__( + 1: ldq_l %0,%1\n + addq %0,%3,%2\n + addq %0,%3,%0\n + stq_c %0,%1\n + beq %0,2f\n + .subsection 2\n + 2: br 1b\n + .previous + :=r (temp), =m (l-a.counter), =r (result) + :Ir (i), m (l-a.counter) : memory); + return result; +} -#define __local_inc(v) ((v)-counter++) -#define __local_dec(v) ((v)-counter++) -#define __local_add(i,v) ((v)-counter+=(i)) -#define __local_sub(i,v) ((v)-counter-=(i)) +static __inline__ long local_sub_return(long i, local_t * l) +{ + long temp, result; + __asm__ __volatile__( + 1: ldq_l %0,%1\n + subq %0,%3,%2\n + subq %0,%3,%0\n + stq_c %0,%1\n + beq %0,2f\n + .subsection 2\n + 2: br 1b\n + .previous + :=r (temp), =m (l-a.counter), =r (result) + :Ir (i), m (l-a.counter) : memory); + return result; +} + +#define local_cmpxchg(l, o, n) \ + (cmpxchg_local(((l)-a.counter), (o), (n))) +#define local_xchg(l, n) (xchg_local(((l)-a.counter), (n))) + +/** + * local_add_unless - add unless the number is a given value + * @l: pointer of type local_t + * @a: the amount to add to l... + * @u: ...unless l is equal to u. + * + * Atomically adds @a to @l, so long as it was not @u. + * Returns non-zero if @l was not @u, and zero otherwise. + */ +#define local_add_unless(l, a, u) \ +({ \ + long c, old;\ + c = local_read(l); \ + for (;;) { \ + if (unlikely(c == (u))) \ + break; \ + old = local_cmpxchg((l), c, c + (a)); \ + if (likely(old == c)) \ + break; \ + c = old;\ + } \ + c != (u); \ +}) +#define local_inc_not_zero(l) local_add_unless((l), 1, 0) + +#define local_add_negative(a, l) (local_add_return((a), (l)) 0) + +#define local_dec_return(l) local_sub_return(1,(l)) + +#define local_inc_return(l) local_add_return(1,(l)) + +#define local_sub_and_test(i,l) (local_sub_return((i), (l)) == 0) + +#define local_inc_and_test(l) (local_add_return(1, (l)) == 0) + +#define local_dec_and_test(l) (local_sub_return(1, (l)) == 0) + +/* Verify if faster than atomic ops */ +#define __local_inc(l) ((l)-a.counter++) +#define __local_dec(l) ((l)-a.counter++) +#define __local_add(i,l) ((l)-a.counter+=(i)) +#define __local_sub(i,l) ((l)-a.counter-=(i)) /* Use these for per-cpu local_t variables: on some archs they are * much more efficient than these naive implementations. Note they take * a variable, not an address. */ -#define cpu_local_read(v) local_read(__get_cpu_var(v)) -#define cpu_local_set(v, i)local_set(__get_cpu_var(v), (i)) - -#define cpu_local_inc(v) local_inc(__get_cpu_var(v)) -#define cpu_local_dec(v) local_dec(__get_cpu_var(v)) -#define cpu_local_add(i, v)local_add((i), __get_cpu_var(v)) -#define cpu_local_sub(i, v)local_sub((i), __get_cpu_var(v)) - -#define __cpu_local_inc(v) __local_inc(__get_cpu_var(v)) -#define __cpu_local_dec(v) __local_dec(__get_cpu_var(v)) -#define __cpu_local_add(i, v) __local_add((i), __get_cpu_var(v)) -#define __cpu_local_sub(i, v) __local_sub((i), __get_cpu_var(v)) +#define cpu_local_read(l) local_read(__get_cpu_var(l)) +#define cpu_local_set(l, i)local_set(__get_cpu_var(l), (i)) + +#define
[PATCH 02/10] local_t : alpha extension
local_t : alpha extension Signed-off-by: Mathieu Desnoyers <[EMAIL PROTECTED]> --- a/include/asm-alpha/local.h +++ b/include/asm-alpha/local.h @@ -4,37 +4,115 @@ #include #include -typedef atomic64_t local_t; +typedef struct +{ + atomic_long_t a; +} local_t; -#define LOCAL_INIT(i) ATOMIC64_INIT(i) -#define local_read(v) atomic64_read(v) -#define local_set(v,i) atomic64_set(v,i) +#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } +#define local_read(l) atomic_long_read(&(l)->a) +#define local_set(l,i) atomic_long_set(&(l)->a, (i)) +#define local_inc(l) atomic_long_inc(&(l)->a) +#define local_dec(l) atomic_long_dec(&(l)->a) +#define local_add(i,l) atomic_long_add((i),(&(l)->a)) +#define local_sub(i,l) atomic_long_sub((i),(&(l)->a)) -#define local_inc(v) atomic64_inc(v) -#define local_dec(v) atomic64_dec(v) -#define local_add(i, v)atomic64_add(i, v) -#define local_sub(i, v)atomic64_sub(i, v) +static __inline__ long local_add_return(long i, local_t * l) +{ + long temp, result; + __asm__ __volatile__( + "1: ldq_l %0,%1\n" + " addq %0,%3,%2\n" + " addq %0,%3,%0\n" + " stq_c %0,%1\n" + " beq %0,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + :"=" (temp), "=m" (l->a.counter), "=" (result) + :"Ir" (i), "m" (l->a.counter) : "memory"); + return result; +} -#define __local_inc(v) ((v)->counter++) -#define __local_dec(v) ((v)->counter++) -#define __local_add(i,v) ((v)->counter+=(i)) -#define __local_sub(i,v) ((v)->counter-=(i)) +static __inline__ long local_sub_return(long i, local_t * v) +{ + long temp, result; + __asm__ __volatile__( + "1: ldq_l %0,%1\n" + " subq %0,%3,%2\n" + " subq %0,%3,%0\n" + " stq_c %0,%1\n" + " beq %0,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + :"=" (temp), "=m" (l->a.counter), "=" (result) + :"Ir" (i), "m" (l->a.counter) : "memory"); + return result; +} + +#define local_cmpxchg(l, old, new) \ + ((long)cmpxchg_local(&((l)->a.counter), old, new)) +#define local_xchg(l, new) (xchg_local(&((l)->a.counter), new)) + +/** + * local_add_unless - add unless the number is a given value + * @l: pointer of type local_t + * @a: the amount to add to l... + * @u: ...unless l is equal to u. + * + * Atomically adds @a to @l, so long as it was not @u. + * Returns non-zero if @l was not @u, and zero otherwise. + */ +#define local_add_unless(l, a, u) \ +({ \ + long c, old;\ + c = local_read(l); \ + for (;;) { \ + if (unlikely(c == (u))) \ + break; \ + old = local_cmpxchg((l), c, c + (a)); \ + if (likely(old == c)) \ + break; \ + c = old;\ + } \ + c != (u); \ +}) +#define local_inc_not_zero(l) local_add_unless((l), 1, 0) + +#define local_add_negative(a, l) (local_add_return((a), (l)) < 0) + +#define local_dec_return(l) local_sub_return(1,(l)) + +#define local_inc_return(l) local_add_return(1,(l)) + +#define local_sub_and_test(i,l) (local_sub_return((i), (l)) == 0) + +#define local_inc_and_test(l) (local_add_return(1, (l)) == 0) + +#define local_dec_and_test(l) (local_sub_return(1, (l)) == 0) + +/* Verify if faster than atomic ops */ +#define __local_inc(l) ((l)->a.counter++) +#define __local_dec(l) ((l)->a.counter++) +#define __local_add(i,l) ((l)->a.counter+=(i)) +#define __local_sub(i,l) ((l)->a.counter-=(i)) /* Use these for per-cpu local_t variables: on some archs they are * much more efficient than these naive implementations. Note they take * a variable, not an address. */ -#define cpu_local_read(v) local_read(&__get_cpu_var(v)) -#define cpu_local_set(v, i)local_set(&__get_cpu_var(v), (i)) - -#define cpu_local_inc(v) local_inc(&__get_cpu_var(v)) -#define cpu_local_dec(v) local_dec(&__get_cpu_var(v)) -#define cpu_local_add(i, v)local_add((i), &__get_cpu_var(v)) -#define cpu_local_sub(i, v)local_sub((i), &__get_cpu_var(v)) - -#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v)) -#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v)) -#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v)) -#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v)) +#define cpu_local_read(l)
[PATCH 02/10] local_t : alpha extension
local_t : alpha extension Signed-off-by: Mathieu Desnoyers [EMAIL PROTECTED] --- a/include/asm-alpha/local.h +++ b/include/asm-alpha/local.h @@ -4,37 +4,115 @@ #include linux/percpu.h #include asm/atomic.h -typedef atomic64_t local_t; +typedef struct +{ + atomic_long_t a; +} local_t; -#define LOCAL_INIT(i) ATOMIC64_INIT(i) -#define local_read(v) atomic64_read(v) -#define local_set(v,i) atomic64_set(v,i) +#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } +#define local_read(l) atomic_long_read((l)-a) +#define local_set(l,i) atomic_long_set((l)-a, (i)) +#define local_inc(l) atomic_long_inc((l)-a) +#define local_dec(l) atomic_long_dec((l)-a) +#define local_add(i,l) atomic_long_add((i),((l)-a)) +#define local_sub(i,l) atomic_long_sub((i),((l)-a)) -#define local_inc(v) atomic64_inc(v) -#define local_dec(v) atomic64_dec(v) -#define local_add(i, v)atomic64_add(i, v) -#define local_sub(i, v)atomic64_sub(i, v) +static __inline__ long local_add_return(long i, local_t * l) +{ + long temp, result; + __asm__ __volatile__( + 1: ldq_l %0,%1\n + addq %0,%3,%2\n + addq %0,%3,%0\n + stq_c %0,%1\n + beq %0,2f\n + .subsection 2\n + 2: br 1b\n + .previous + :=r (temp), =m (l-a.counter), =r (result) + :Ir (i), m (l-a.counter) : memory); + return result; +} -#define __local_inc(v) ((v)-counter++) -#define __local_dec(v) ((v)-counter++) -#define __local_add(i,v) ((v)-counter+=(i)) -#define __local_sub(i,v) ((v)-counter-=(i)) +static __inline__ long local_sub_return(long i, local_t * v) +{ + long temp, result; + __asm__ __volatile__( + 1: ldq_l %0,%1\n + subq %0,%3,%2\n + subq %0,%3,%0\n + stq_c %0,%1\n + beq %0,2f\n + .subsection 2\n + 2: br 1b\n + .previous + :=r (temp), =m (l-a.counter), =r (result) + :Ir (i), m (l-a.counter) : memory); + return result; +} + +#define local_cmpxchg(l, old, new) \ + ((long)cmpxchg_local(((l)-a.counter), old, new)) +#define local_xchg(l, new) (xchg_local(((l)-a.counter), new)) + +/** + * local_add_unless - add unless the number is a given value + * @l: pointer of type local_t + * @a: the amount to add to l... + * @u: ...unless l is equal to u. + * + * Atomically adds @a to @l, so long as it was not @u. + * Returns non-zero if @l was not @u, and zero otherwise. + */ +#define local_add_unless(l, a, u) \ +({ \ + long c, old;\ + c = local_read(l); \ + for (;;) { \ + if (unlikely(c == (u))) \ + break; \ + old = local_cmpxchg((l), c, c + (a)); \ + if (likely(old == c)) \ + break; \ + c = old;\ + } \ + c != (u); \ +}) +#define local_inc_not_zero(l) local_add_unless((l), 1, 0) + +#define local_add_negative(a, l) (local_add_return((a), (l)) 0) + +#define local_dec_return(l) local_sub_return(1,(l)) + +#define local_inc_return(l) local_add_return(1,(l)) + +#define local_sub_and_test(i,l) (local_sub_return((i), (l)) == 0) + +#define local_inc_and_test(l) (local_add_return(1, (l)) == 0) + +#define local_dec_and_test(l) (local_sub_return(1, (l)) == 0) + +/* Verify if faster than atomic ops */ +#define __local_inc(l) ((l)-a.counter++) +#define __local_dec(l) ((l)-a.counter++) +#define __local_add(i,l) ((l)-a.counter+=(i)) +#define __local_sub(i,l) ((l)-a.counter-=(i)) /* Use these for per-cpu local_t variables: on some archs they are * much more efficient than these naive implementations. Note they take * a variable, not an address. */ -#define cpu_local_read(v) local_read(__get_cpu_var(v)) -#define cpu_local_set(v, i)local_set(__get_cpu_var(v), (i)) - -#define cpu_local_inc(v) local_inc(__get_cpu_var(v)) -#define cpu_local_dec(v) local_dec(__get_cpu_var(v)) -#define cpu_local_add(i, v)local_add((i), __get_cpu_var(v)) -#define cpu_local_sub(i, v)local_sub((i), __get_cpu_var(v)) - -#define __cpu_local_inc(v) __local_inc(__get_cpu_var(v)) -#define __cpu_local_dec(v) __local_dec(__get_cpu_var(v)) -#define __cpu_local_add(i, v) __local_add((i), __get_cpu_var(v)) -#define __cpu_local_sub(i, v) __local_sub((i), __get_cpu_var(v)) +#define cpu_local_read(l) local_read(__get_cpu_var(l)) +#define cpu_local_set(l, i)local_set(__get_cpu_var(l), (i))
[PATCH 02/10] local_t : alpha extension
local_t : alpha extension Signed-off-by: Mathieu Desnoyers <[EMAIL PROTECTED]> --- a/include/asm-alpha/local.h +++ b/include/asm-alpha/local.h @@ -4,37 +4,115 @@ #include #include -typedef atomic64_t local_t; +typedef struct +{ + atomic_long_t a; +} local_t; -#define LOCAL_INIT(i) ATOMIC64_INIT(i) -#define local_read(v) atomic64_read(v) -#define local_set(v,i) atomic64_set(v,i) +#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } +#define local_read(l) atomic_long_read(&(l)->a) +#define local_set(l,i) atomic_long_set(&(l)->a, (i)) +#define local_inc(l) atomic_long_inc(&(l)->a) +#define local_dec(l) atomic_long_dec(&(l)->a) +#define local_add(i,l) atomic_long_add((i),(&(l)->a)) +#define local_sub(i,l) atomic_long_sub((i),(&(l)->a)) -#define local_inc(v) atomic64_inc(v) -#define local_dec(v) atomic64_dec(v) -#define local_add(i, v)atomic64_add(i, v) -#define local_sub(i, v)atomic64_sub(i, v) +static __inline__ long local_add_return(long i, local_t * l) +{ + long temp, result; + __asm__ __volatile__( + "1: ldq_l %0,%1\n" + " addq %0,%3,%2\n" + " addq %0,%3,%0\n" + " stq_c %0,%1\n" + " beq %0,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + :"=" (temp), "=m" (l->a.counter), "=" (result) + :"Ir" (i), "m" (l->a.counter) : "memory"); + return result; +} -#define __local_inc(v) ((v)->counter++) -#define __local_dec(v) ((v)->counter++) -#define __local_add(i,v) ((v)->counter+=(i)) -#define __local_sub(i,v) ((v)->counter-=(i)) +static __inline__ long local_sub_return(long i, local_t * v) +{ + long temp, result; + __asm__ __volatile__( + "1: ldq_l %0,%1\n" + " subq %0,%3,%2\n" + " subq %0,%3,%0\n" + " stq_c %0,%1\n" + " beq %0,2f\n" + ".subsection 2\n" + "2: br 1b\n" + ".previous" + :"=" (temp), "=m" (l->a.counter), "=" (result) + :"Ir" (i), "m" (l->a.counter) : "memory"); + return result; +} + +#define local_cmpxchg(l, old, new) \ + ((long)cmpxchg_local(&((l)->a.counter), old, new)) +#define local_xchg(l, new) (xchg_local(&((l)->a.counter), new)) + +/** + * local_add_unless - add unless the number is a given value + * @l: pointer of type local_t + * @a: the amount to add to l... + * @u: ...unless l is equal to u. + * + * Atomically adds @a to @l, so long as it was not @u. + * Returns non-zero if @l was not @u, and zero otherwise. + */ +#define local_add_unless(l, a, u) \ +({ \ + long c, old;\ + c = local_read(l); \ + for (;;) { \ + if (unlikely(c == (u))) \ + break; \ + old = local_cmpxchg((l), c, c + (a)); \ + if (likely(old == c)) \ + break; \ + c = old;\ + } \ + c != (u); \ +}) +#define local_inc_not_zero(l) local_add_unless((l), 1, 0) + +#define local_add_negative(a, l) (local_add_return((a), (l)) < 0) + +#define local_dec_return(l) local_sub_return(1,(l)) + +#define local_inc_return(l) local_add_return(1,(l)) + +#define local_sub_and_test(i,l) (local_sub_return((i), (l)) == 0) + +#define local_inc_and_test(l) (local_add_return(1, (l)) == 0) + +#define local_dec_and_test(l) (local_sub_return(1, (l)) == 0) + +/* Verify if faster than atomic ops */ +#define __local_inc(l) ((l)->a.counter++) +#define __local_dec(l) ((l)->a.counter++) +#define __local_add(i,l) ((l)->a.counter+=(i)) +#define __local_sub(i,l) ((l)->a.counter-=(i)) /* Use these for per-cpu local_t variables: on some archs they are * much more efficient than these naive implementations. Note they take * a variable, not an address. */ -#define cpu_local_read(v) local_read(&__get_cpu_var(v)) -#define cpu_local_set(v, i)local_set(&__get_cpu_var(v), (i)) - -#define cpu_local_inc(v) local_inc(&__get_cpu_var(v)) -#define cpu_local_dec(v) local_dec(&__get_cpu_var(v)) -#define cpu_local_add(i, v)local_add((i), &__get_cpu_var(v)) -#define cpu_local_sub(i, v)local_sub((i), &__get_cpu_var(v)) - -#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v)) -#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v)) -#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v)) -#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v)) +#define cpu_local_read(l)
[PATCH 02/10] local_t : alpha extension
local_t : alpha extension Signed-off-by: Mathieu Desnoyers [EMAIL PROTECTED] --- a/include/asm-alpha/local.h +++ b/include/asm-alpha/local.h @@ -4,37 +4,115 @@ #include linux/percpu.h #include asm/atomic.h -typedef atomic64_t local_t; +typedef struct +{ + atomic_long_t a; +} local_t; -#define LOCAL_INIT(i) ATOMIC64_INIT(i) -#define local_read(v) atomic64_read(v) -#define local_set(v,i) atomic64_set(v,i) +#define LOCAL_INIT(i) { ATOMIC_LONG_INIT(i) } +#define local_read(l) atomic_long_read((l)-a) +#define local_set(l,i) atomic_long_set((l)-a, (i)) +#define local_inc(l) atomic_long_inc((l)-a) +#define local_dec(l) atomic_long_dec((l)-a) +#define local_add(i,l) atomic_long_add((i),((l)-a)) +#define local_sub(i,l) atomic_long_sub((i),((l)-a)) -#define local_inc(v) atomic64_inc(v) -#define local_dec(v) atomic64_dec(v) -#define local_add(i, v)atomic64_add(i, v) -#define local_sub(i, v)atomic64_sub(i, v) +static __inline__ long local_add_return(long i, local_t * l) +{ + long temp, result; + __asm__ __volatile__( + 1: ldq_l %0,%1\n + addq %0,%3,%2\n + addq %0,%3,%0\n + stq_c %0,%1\n + beq %0,2f\n + .subsection 2\n + 2: br 1b\n + .previous + :=r (temp), =m (l-a.counter), =r (result) + :Ir (i), m (l-a.counter) : memory); + return result; +} -#define __local_inc(v) ((v)-counter++) -#define __local_dec(v) ((v)-counter++) -#define __local_add(i,v) ((v)-counter+=(i)) -#define __local_sub(i,v) ((v)-counter-=(i)) +static __inline__ long local_sub_return(long i, local_t * v) +{ + long temp, result; + __asm__ __volatile__( + 1: ldq_l %0,%1\n + subq %0,%3,%2\n + subq %0,%3,%0\n + stq_c %0,%1\n + beq %0,2f\n + .subsection 2\n + 2: br 1b\n + .previous + :=r (temp), =m (l-a.counter), =r (result) + :Ir (i), m (l-a.counter) : memory); + return result; +} + +#define local_cmpxchg(l, old, new) \ + ((long)cmpxchg_local(((l)-a.counter), old, new)) +#define local_xchg(l, new) (xchg_local(((l)-a.counter), new)) + +/** + * local_add_unless - add unless the number is a given value + * @l: pointer of type local_t + * @a: the amount to add to l... + * @u: ...unless l is equal to u. + * + * Atomically adds @a to @l, so long as it was not @u. + * Returns non-zero if @l was not @u, and zero otherwise. + */ +#define local_add_unless(l, a, u) \ +({ \ + long c, old;\ + c = local_read(l); \ + for (;;) { \ + if (unlikely(c == (u))) \ + break; \ + old = local_cmpxchg((l), c, c + (a)); \ + if (likely(old == c)) \ + break; \ + c = old;\ + } \ + c != (u); \ +}) +#define local_inc_not_zero(l) local_add_unless((l), 1, 0) + +#define local_add_negative(a, l) (local_add_return((a), (l)) 0) + +#define local_dec_return(l) local_sub_return(1,(l)) + +#define local_inc_return(l) local_add_return(1,(l)) + +#define local_sub_and_test(i,l) (local_sub_return((i), (l)) == 0) + +#define local_inc_and_test(l) (local_add_return(1, (l)) == 0) + +#define local_dec_and_test(l) (local_sub_return(1, (l)) == 0) + +/* Verify if faster than atomic ops */ +#define __local_inc(l) ((l)-a.counter++) +#define __local_dec(l) ((l)-a.counter++) +#define __local_add(i,l) ((l)-a.counter+=(i)) +#define __local_sub(i,l) ((l)-a.counter-=(i)) /* Use these for per-cpu local_t variables: on some archs they are * much more efficient than these naive implementations. Note they take * a variable, not an address. */ -#define cpu_local_read(v) local_read(__get_cpu_var(v)) -#define cpu_local_set(v, i)local_set(__get_cpu_var(v), (i)) - -#define cpu_local_inc(v) local_inc(__get_cpu_var(v)) -#define cpu_local_dec(v) local_dec(__get_cpu_var(v)) -#define cpu_local_add(i, v)local_add((i), __get_cpu_var(v)) -#define cpu_local_sub(i, v)local_sub((i), __get_cpu_var(v)) - -#define __cpu_local_inc(v) __local_inc(__get_cpu_var(v)) -#define __cpu_local_dec(v) __local_dec(__get_cpu_var(v)) -#define __cpu_local_add(i, v) __local_add((i), __get_cpu_var(v)) -#define __cpu_local_sub(i, v) __local_sub((i), __get_cpu_var(v)) +#define cpu_local_read(l) local_read(__get_cpu_var(l)) +#define cpu_local_set(l, i)local_set(__get_cpu_var(l),