Re: [PATCH 07/10] local_t : powerpc extension

2007-02-15 Thread Kumar Gala


On Feb 15, 2007, at 1:20 AM, Mathieu Desnoyers wrote:


* Andrew Morton ([EMAIL PROTECTED]) wrote:
On Sun, 11 Feb 2007 14:18:12 -0500 Mathieu Desnoyers  
<[EMAIL PROTECTED]> wrote:



local_t : powerpc extension


This diff contains changes which are also present in "[PATCH 07/10]
atomic.h : Add atomic64 cmpxchg, xchg and add_unless to powerpc",  
resulting

in rather a mess.

I dropped the duplicated hunks from the later patch rather than  
this one,

but I haven't tried to compile the result yet.



Yes, sorry about that : the atomic.h diff has been duplicated in both
the local and atomic changes.

The change to system.h for local.h is to add the xchg_local and
cmpxchg_local, while the change for atomic.h is to simply remove the
#include  from system.h.

Here is a proper local.h diff, if it happens to become necessary, but
simply removing the duplicated asm-powerpc/system.h hunks will be ok.

Thanks,

Signed-off-by: Mathieu Desnoyers <[EMAIL PROTECTED]>

--- a/include/asm-powerpc/local.h
+++ b/include/asm-powerpc/local.h
@@ -1 +1,342 @@
-#include 
+#ifndef _ARCH_POWERPC_LOCAL_H
+#define _ARCH_POWERPC_LOCAL_H
+
+#include 
+#include 
+
+typedef struct
+{
+   atomic_long_t a;
+} local_t;
+
+#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_add(i,l) atomic_long_add((i),(&(l)->a))
+#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
+#define local_inc(l)   atomic_long_inc(&(l)->a)
+#define local_dec(l)   atomic_long_dec(&(l)->a)
+
+#ifndef __powerpc64__
+
+static __inline__ int local_add_return(int a, local_t *l)
+{


is there a reason this isn't local_add_return(long a, local_t *l) on  
ppc32?


(same comment for other functions)

- k



-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 07/10] local_t : powerpc extension

2007-02-15 Thread Kumar Gala


On Feb 15, 2007, at 1:20 AM, Mathieu Desnoyers wrote:


* Andrew Morton ([EMAIL PROTECTED]) wrote:
On Sun, 11 Feb 2007 14:18:12 -0500 Mathieu Desnoyers  
[EMAIL PROTECTED] wrote:



local_t : powerpc extension


This diff contains changes which are also present in [PATCH 07/10]
atomic.h : Add atomic64 cmpxchg, xchg and add_unless to powerpc,  
resulting

in rather a mess.

I dropped the duplicated hunks from the later patch rather than  
this one,

but I haven't tried to compile the result yet.



Yes, sorry about that : the atomic.h diff has been duplicated in both
the local and atomic changes.

The change to system.h for local.h is to add the xchg_local and
cmpxchg_local, while the change for atomic.h is to simply remove the
#include asm/atomic.h from system.h.

Here is a proper local.h diff, if it happens to become necessary, but
simply removing the duplicated asm-powerpc/system.h hunks will be ok.

Thanks,

Signed-off-by: Mathieu Desnoyers [EMAIL PROTECTED]

--- a/include/asm-powerpc/local.h
+++ b/include/asm-powerpc/local.h
@@ -1 +1,342 @@
-#include asm-generic/local.h
+#ifndef _ARCH_POWERPC_LOCAL_H
+#define _ARCH_POWERPC_LOCAL_H
+
+#include linux/percpu.h
+#include asm/atomic.h
+
+typedef struct
+{
+   atomic_long_t a;
+} local_t;
+
+#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_add(i,l) atomic_long_add((i),((l)-a))
+#define local_sub(i,l) atomic_long_sub((i),((l)-a))
+#define local_inc(l)   atomic_long_inc((l)-a)
+#define local_dec(l)   atomic_long_dec((l)-a)
+
+#ifndef __powerpc64__
+
+static __inline__ int local_add_return(int a, local_t *l)
+{


is there a reason this isn't local_add_return(long a, local_t *l) on  
ppc32?


(same comment for other functions)

- k



-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 07/10] local_t : powerpc extension

2007-02-14 Thread Mathieu Desnoyers
* Andrew Morton ([EMAIL PROTECTED]) wrote:
> On Sun, 11 Feb 2007 14:18:12 -0500 Mathieu Desnoyers <[EMAIL PROTECTED]> 
> wrote:
> 
> > local_t : powerpc extension
> 
> This diff contains changes which are also present in "[PATCH 07/10]
> atomic.h : Add atomic64 cmpxchg, xchg and add_unless to powerpc", resulting
> in rather a mess.
> 
> I dropped the duplicated hunks from the later patch rather than this one,
> but I haven't tried to compile the result yet.
> 

Yes, sorry about that : the atomic.h diff has been duplicated in both
the local and atomic changes.

The change to system.h for local.h is to add the xchg_local and
cmpxchg_local, while the change for atomic.h is to simply remove the
#include  from system.h.

Here is a proper local.h diff, if it happens to become necessary, but
simply removing the duplicated asm-powerpc/system.h hunks will be ok.

Thanks,

Signed-off-by: Mathieu Desnoyers <[EMAIL PROTECTED]>

--- a/include/asm-powerpc/local.h
+++ b/include/asm-powerpc/local.h
@@ -1 +1,342 @@
-#include 
+#ifndef _ARCH_POWERPC_LOCAL_H
+#define _ARCH_POWERPC_LOCAL_H
+
+#include 
+#include 
+
+typedef struct
+{
+   atomic_long_t a;
+} local_t;
+
+#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_add(i,l) atomic_long_add((i),(&(l)->a))
+#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
+#define local_inc(l)   atomic_long_inc(&(l)->a)
+#define local_dec(l)   atomic_long_dec(&(l)->a)
+
+#ifndef __powerpc64__
+
+static __inline__ int local_add_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%2 # local_add_return\n\
+   add %0,%1,%0\n"
+   PPC405_ERR77(0,%2)
+"  stwcx.  %0,0,%2 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (a), "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+#define local_add_negative(a, l)   (local_add_return((a), (l)) < 0)
+
+static __inline__ int local_sub_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%2 # local_sub_return\n\
+   subf%0,%1,%0\n"
+   PPC405_ERR77(0,%2)
+"  stwcx.  %0,0,%2 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (a), "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+static __inline__ int local_inc_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%1 # local_inc_return\n\
+   addic   %0,%0,1\n"
+   PPC405_ERR77(0,%1)
+"  stwcx.  %0,0,%1 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+/*
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+static __inline__ int local_dec_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%1 # local_dec_return\n\
+   addic   %0,%0,-1\n"
+   PPC405_ERR77(0,%1)
+"  stwcx.  %0,0,%1\n\
+   bne-1b"
+   : "=" (t)
+   : "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+#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 v...
+ * @u: ...unless v 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.
+ */
+static __inline__ int local_add_unless(local_t *l, int a, int u)
+{
+   int t;
+
+   __asm__ __volatile__ (
+"1:lwarx   %0,0,%1 # local_add_unless\n\
+   cmpw0,%0,%3 \n\
+   beq-2f \n\
+   add %0,%2,%0 \n"
+   PPC405_ERR77(0,%2)
+"  stwcx.  %0,0,%1 \n\
+   bne-1b \n"
+"  subf%0,%2,%0 \n\
+2:"
+   : "=" (t)
+   : "r" (&(l->a.counter)), "r" (a), "r" (u)
+   : "cc", "memory");
+
+   return t != u;
+}
+
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_sub_and_test(a, l)   (local_sub_return((a), (l)) == 0)
+#define local_dec_and_test(l)  (local_dec_return((l)) == 0)
+
+/*
+ * Atomically test *l and decrement if it is greater than 0.
+ * The function returns the old value of *l minus 1.
+ */
+static __inline__ int local_dec_if_positive(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%1 # local_dec_if_positive\n\
+   cmpwi   %0,1\n\
+   addi%0,%0,-1\n\
+   blt-2f\n"
+   PPC405_ERR77(0,%1)
+"  stwcx.  %0,0,%1\n\
+   bne-1b"
+   "\n\
+2:": "=" (t)
+   : "r" 

Re: [PATCH 07/10] local_t : powerpc extension

2007-02-14 Thread Andrew Morton
On Sun, 11 Feb 2007 14:18:12 -0500 Mathieu Desnoyers <[EMAIL PROTECTED]> wrote:

> local_t : powerpc extension

This diff contains changes which are also present in "[PATCH 07/10]
atomic.h : Add atomic64 cmpxchg, xchg and add_unless to powerpc", resulting
in rather a mess.

I dropped the duplicated hunks from the later patch rather than this one,
but I haven't tried to compile the result yet.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 07/10] local_t : powerpc extension

2007-02-14 Thread Andrew Morton
On Sun, 11 Feb 2007 14:18:12 -0500 Mathieu Desnoyers [EMAIL PROTECTED] wrote:

 local_t : powerpc extension

This diff contains changes which are also present in [PATCH 07/10]
atomic.h : Add atomic64 cmpxchg, xchg and add_unless to powerpc, resulting
in rather a mess.

I dropped the duplicated hunks from the later patch rather than this one,
but I haven't tried to compile the result yet.

-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 07/10] local_t : powerpc extension

2007-02-14 Thread Mathieu Desnoyers
* Andrew Morton ([EMAIL PROTECTED]) wrote:
 On Sun, 11 Feb 2007 14:18:12 -0500 Mathieu Desnoyers [EMAIL PROTECTED] 
 wrote:
 
  local_t : powerpc extension
 
 This diff contains changes which are also present in [PATCH 07/10]
 atomic.h : Add atomic64 cmpxchg, xchg and add_unless to powerpc, resulting
 in rather a mess.
 
 I dropped the duplicated hunks from the later patch rather than this one,
 but I haven't tried to compile the result yet.
 

Yes, sorry about that : the atomic.h diff has been duplicated in both
the local and atomic changes.

The change to system.h for local.h is to add the xchg_local and
cmpxchg_local, while the change for atomic.h is to simply remove the
#include asm/atomic.h from system.h.

Here is a proper local.h diff, if it happens to become necessary, but
simply removing the duplicated asm-powerpc/system.h hunks will be ok.

Thanks,

Signed-off-by: Mathieu Desnoyers [EMAIL PROTECTED]

--- a/include/asm-powerpc/local.h
+++ b/include/asm-powerpc/local.h
@@ -1 +1,342 @@
-#include asm-generic/local.h
+#ifndef _ARCH_POWERPC_LOCAL_H
+#define _ARCH_POWERPC_LOCAL_H
+
+#include linux/percpu.h
+#include asm/atomic.h
+
+typedef struct
+{
+   atomic_long_t a;
+} local_t;
+
+#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_add(i,l) atomic_long_add((i),((l)-a))
+#define local_sub(i,l) atomic_long_sub((i),((l)-a))
+#define local_inc(l)   atomic_long_inc((l)-a)
+#define local_dec(l)   atomic_long_dec((l)-a)
+
+#ifndef __powerpc64__
+
+static __inline__ int local_add_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%2 # local_add_return\n\
+   add %0,%1,%0\n
+   PPC405_ERR77(0,%2)
+  stwcx.  %0,0,%2 \n\
+   bne-1b
+   : =r (t)
+   : r (a), r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+#define local_add_negative(a, l)   (local_add_return((a), (l))  0)
+
+static __inline__ int local_sub_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%2 # local_sub_return\n\
+   subf%0,%1,%0\n
+   PPC405_ERR77(0,%2)
+  stwcx.  %0,0,%2 \n\
+   bne-1b
+   : =r (t)
+   : r (a), r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+static __inline__ int local_inc_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%1 # local_inc_return\n\
+   addic   %0,%0,1\n
+   PPC405_ERR77(0,%1)
+  stwcx.  %0,0,%1 \n\
+   bne-1b
+   : =r (t)
+   : r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+/*
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+static __inline__ int local_dec_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%1 # local_dec_return\n\
+   addic   %0,%0,-1\n
+   PPC405_ERR77(0,%1)
+  stwcx.  %0,0,%1\n\
+   bne-1b
+   : =r (t)
+   : r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+#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 v...
+ * @u: ...unless v 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.
+ */
+static __inline__ int local_add_unless(local_t *l, int a, int u)
+{
+   int t;
+
+   __asm__ __volatile__ (
+1:lwarx   %0,0,%1 # local_add_unless\n\
+   cmpw0,%0,%3 \n\
+   beq-2f \n\
+   add %0,%2,%0 \n
+   PPC405_ERR77(0,%2)
+  stwcx.  %0,0,%1 \n\
+   bne-1b \n
+  subf%0,%2,%0 \n\
+2:
+   : =r (t)
+   : r ((l-a.counter)), r (a), r (u)
+   : cc, memory);
+
+   return t != u;
+}
+
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_sub_and_test(a, l)   (local_sub_return((a), (l)) == 0)
+#define local_dec_and_test(l)  (local_dec_return((l)) == 0)
+
+/*
+ * Atomically test *l and decrement if it is greater than 0.
+ * The function returns the old value of *l minus 1.
+ */
+static __inline__ int local_dec_if_positive(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%1 # local_dec_if_positive\n\
+   cmpwi   %0,1\n\
+   addi%0,%0,-1\n\
+   blt-2f\n
+   PPC405_ERR77(0,%1)
+  stwcx.  %0,0,%1\n\
+   bne-1b
+   \n\
+2:: =b (t)
+   : r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+

[PATCH 07/10] local_t : powerpc extension

2007-02-11 Thread Mathieu Desnoyers
local_t : powerpc extension

Signed-off-by: Mathieu Desnoyers <[EMAIL PROTECTED]>

--- a/include/asm-powerpc/local.h
+++ b/include/asm-powerpc/local.h
@@ -1 +1,342 @@
-#include 
+#ifndef _ARCH_POWERPC_LOCAL_H
+#define _ARCH_POWERPC_LOCAL_H
+
+#include 
+#include 
+
+typedef struct
+{
+   atomic_long_t a;
+} local_t;
+
+#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_add(i,l) atomic_long_add((i),(&(l)->a))
+#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
+#define local_inc(l)   atomic_long_inc(&(l)->a)
+#define local_dec(l)   atomic_long_dec(&(l)->a)
+
+#ifndef __powerpc64__
+
+static __inline__ int local_add_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%2 # local_add_return\n\
+   add %0,%1,%0\n"
+   PPC405_ERR77(0,%2)
+"  stwcx.  %0,0,%2 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (a), "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+#define local_add_negative(a, l)   (local_add_return((a), (l)) < 0)
+
+static __inline__ int local_sub_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%2 # local_sub_return\n\
+   subf%0,%1,%0\n"
+   PPC405_ERR77(0,%2)
+"  stwcx.  %0,0,%2 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (a), "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+static __inline__ int local_inc_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%1 # local_inc_return\n\
+   addic   %0,%0,1\n"
+   PPC405_ERR77(0,%1)
+"  stwcx.  %0,0,%1 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+/*
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+static __inline__ int local_dec_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%1 # local_dec_return\n\
+   addic   %0,%0,-1\n"
+   PPC405_ERR77(0,%1)
+"  stwcx.  %0,0,%1\n\
+   bne-1b"
+   : "=" (t)
+   : "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+#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 v...
+ * @u: ...unless v 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.
+ */
+static __inline__ int local_add_unless(local_t *l, int a, int u)
+{
+   int t;
+
+   __asm__ __volatile__ (
+"1:lwarx   %0,0,%1 # local_add_unless\n\
+   cmpw0,%0,%3 \n\
+   beq-2f \n\
+   add %0,%2,%0 \n"
+   PPC405_ERR77(0,%2)
+"  stwcx.  %0,0,%1 \n\
+   bne-1b \n"
+"  subf%0,%2,%0 \n\
+2:"
+   : "=" (t)
+   : "r" (&(l->a.counter)), "r" (a), "r" (u)
+   : "cc", "memory");
+
+   return t != u;
+}
+
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_sub_and_test(a, l)   (local_sub_return((a), (l)) == 0)
+#define local_dec_and_test(l)  (local_dec_return((l)) == 0)
+
+/*
+ * Atomically test *l and decrement if it is greater than 0.
+ * The function returns the old value of *l minus 1.
+ */
+static __inline__ int local_dec_if_positive(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%1 # local_dec_if_positive\n\
+   cmpwi   %0,1\n\
+   addi%0,%0,-1\n\
+   blt-2f\n"
+   PPC405_ERR77(0,%1)
+"  stwcx.  %0,0,%1\n\
+   bne-1b"
+   "\n\
+2:": "=" (t)
+   : "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+#else /* __powerpc64__ */
+
+static __inline__ long local_add_return(long a, local_t *l)
+{
+   long t;
+
+   __asm__ __volatile__(
+"1:ldarx   %0,0,%2 # local_add_return\n\
+   add %0,%1,%0\n\
+   stdcx.  %0,0,%2 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (a), "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+#define local_add_negative(a, l)   (local_add_return((a), (l)) < 0)
+
+static __inline__ long local_sub_return(long a, local_t *l)
+{
+   long t;
+
+   __asm__ __volatile__(
+"1:ldarx   %0,0,%2 # local_sub_return\n\
+   subf%0,%1,%0\n\
+   stdcx.  %0,0,%2 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (a), "r" (&(l->a.counter))
+   : "cc", 

[PATCH 07/10] local_t : powerpc extension

2007-02-11 Thread Mathieu Desnoyers
local_t : powerpc extension

Signed-off-by: Mathieu Desnoyers [EMAIL PROTECTED]

--- a/include/asm-powerpc/local.h
+++ b/include/asm-powerpc/local.h
@@ -1 +1,342 @@
-#include asm-generic/local.h
+#ifndef _ARCH_POWERPC_LOCAL_H
+#define _ARCH_POWERPC_LOCAL_H
+
+#include linux/percpu.h
+#include asm/atomic.h
+
+typedef struct
+{
+   atomic_long_t a;
+} local_t;
+
+#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_add(i,l) atomic_long_add((i),((l)-a))
+#define local_sub(i,l) atomic_long_sub((i),((l)-a))
+#define local_inc(l)   atomic_long_inc((l)-a)
+#define local_dec(l)   atomic_long_dec((l)-a)
+
+#ifndef __powerpc64__
+
+static __inline__ int local_add_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%2 # local_add_return\n\
+   add %0,%1,%0\n
+   PPC405_ERR77(0,%2)
+  stwcx.  %0,0,%2 \n\
+   bne-1b
+   : =r (t)
+   : r (a), r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+#define local_add_negative(a, l)   (local_add_return((a), (l))  0)
+
+static __inline__ int local_sub_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%2 # local_sub_return\n\
+   subf%0,%1,%0\n
+   PPC405_ERR77(0,%2)
+  stwcx.  %0,0,%2 \n\
+   bne-1b
+   : =r (t)
+   : r (a), r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+static __inline__ int local_inc_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%1 # local_inc_return\n\
+   addic   %0,%0,1\n
+   PPC405_ERR77(0,%1)
+  stwcx.  %0,0,%1 \n\
+   bne-1b
+   : =r (t)
+   : r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+/*
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+static __inline__ int local_dec_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%1 # local_dec_return\n\
+   addic   %0,%0,-1\n
+   PPC405_ERR77(0,%1)
+  stwcx.  %0,0,%1\n\
+   bne-1b
+   : =r (t)
+   : r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+#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 v...
+ * @u: ...unless v 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.
+ */
+static __inline__ int local_add_unless(local_t *l, int a, int u)
+{
+   int t;
+
+   __asm__ __volatile__ (
+1:lwarx   %0,0,%1 # local_add_unless\n\
+   cmpw0,%0,%3 \n\
+   beq-2f \n\
+   add %0,%2,%0 \n
+   PPC405_ERR77(0,%2)
+  stwcx.  %0,0,%1 \n\
+   bne-1b \n
+  subf%0,%2,%0 \n\
+2:
+   : =r (t)
+   : r ((l-a.counter)), r (a), r (u)
+   : cc, memory);
+
+   return t != u;
+}
+
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_sub_and_test(a, l)   (local_sub_return((a), (l)) == 0)
+#define local_dec_and_test(l)  (local_dec_return((l)) == 0)
+
+/*
+ * Atomically test *l and decrement if it is greater than 0.
+ * The function returns the old value of *l minus 1.
+ */
+static __inline__ int local_dec_if_positive(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%1 # local_dec_if_positive\n\
+   cmpwi   %0,1\n\
+   addi%0,%0,-1\n\
+   blt-2f\n
+   PPC405_ERR77(0,%1)
+  stwcx.  %0,0,%1\n\
+   bne-1b
+   \n\
+2:: =b (t)
+   : r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+#else /* __powerpc64__ */
+
+static __inline__ long local_add_return(long a, local_t *l)
+{
+   long t;
+
+   __asm__ __volatile__(
+1:ldarx   %0,0,%2 # local_add_return\n\
+   add %0,%1,%0\n\
+   stdcx.  %0,0,%2 \n\
+   bne-1b
+   : =r (t)
+   : r (a), r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+#define local_add_negative(a, l)   (local_add_return((a), (l))  0)
+
+static __inline__ long local_sub_return(long a, local_t *l)
+{
+   long t;
+
+   __asm__ __volatile__(
+1:ldarx   %0,0,%2 # local_sub_return\n\
+   subf%0,%1,%0\n\
+   stdcx.  %0,0,%2 \n\
+   bne-1b
+   : =r (t)
+   : r (a), r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+static __inline__ long local_inc_return(local_t *l)
+{
+  

[PATCH 07/10] local_t : powerpc extension

2007-01-25 Thread Mathieu Desnoyers
local_t : powerpc extension

Signed-off-by: Mathieu Desnoyers <[EMAIL PROTECTED]>
--- a/include/asm-powerpc/local.h
+++ b/include/asm-powerpc/local.h
@@ -1 +1,342 @@
-#include 
+#ifndef _ARCH_POWERPC_LOCAL_H
+#define _ARCH_POWERPC_LOCAL_H
+
+#include 
+#include 
+
+typedef struct
+{
+   atomic_long_t a;
+} local_t;
+
+#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_add(i,l) atomic_long_add((i),(&(l)->a))
+#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
+#define local_inc(l)   atomic_long_inc(&(l)->a)
+#define local_dec(l)   atomic_long_dec(&(l)->a)
+
+#ifndef __powerpc64__
+
+static __inline__ int local_add_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%2 # local_add_return\n\
+   add %0,%1,%0\n"
+   PPC405_ERR77(0,%2)
+"  stwcx.  %0,0,%2 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (a), "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+#define local_add_negative(a, l)   (local_add_return((a), (l)) < 0)
+
+static __inline__ int local_sub_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%2 # local_sub_return\n\
+   subf%0,%1,%0\n"
+   PPC405_ERR77(0,%2)
+"  stwcx.  %0,0,%2 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (a), "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+static __inline__ int local_inc_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%1 # local_inc_return\n\
+   addic   %0,%0,1\n"
+   PPC405_ERR77(0,%1)
+"  stwcx.  %0,0,%1 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+/*
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+static __inline__ int local_dec_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%1 # local_dec_return\n\
+   addic   %0,%0,-1\n"
+   PPC405_ERR77(0,%1)
+"  stwcx.  %0,0,%1\n\
+   bne-1b"
+   : "=" (t)
+   : "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+#define local_cmpxchg(l, o, n) \
+   ((long)cmpxchg(&((l)->a.counter), (o), (n)))
+#define local_xchg(l, new) (xchg(&((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 v...
+ * @u: ...unless v 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.
+ */
+static __inline__ int local_add_unless(local_t *l, int a, int u)
+{
+   int t;
+
+   __asm__ __volatile__ (
+"1:lwarx   %0,0,%1 # local_add_unless\n\
+   cmpw0,%0,%3 \n\
+   beq-2f \n\
+   add %0,%2,%0 \n"
+   PPC405_ERR77(0,%2)
+"  stwcx.  %0,0,%1 \n\
+   bne-1b \n"
+"  subf%0,%2,%0 \n\
+2:"
+   : "=" (t)
+   : "r" (&(l->a.counter)), "r" (a), "r" (u)
+   : "cc", "memory");
+
+   return t != u;
+}
+
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_sub_and_test(a, l)   (local_sub_return((a), (l)) == 0)
+#define local_dec_and_test(l)  (local_dec_return((l)) == 0)
+
+/*
+ * Atomically test *l and decrement if it is greater than 0.
+ * The function returns the old value of *l minus 1.
+ */
+static __inline__ int local_dec_if_positive(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%1 # local_dec_if_positive\n\
+   cmpwi   %0,1\n\
+   addi%0,%0,-1\n\
+   blt-2f\n"
+   PPC405_ERR77(0,%1)
+"  stwcx.  %0,0,%1\n\
+   bne-1b"
+   "\n\
+2:": "=" (t)
+   : "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+#else /* __powerpc64__ */
+
+static __inline__ long local_add_return(long a, local_t *l)
+{
+   long t;
+
+   __asm__ __volatile__(
+"1:ldarx   %0,0,%2 # local_add_return\n\
+   add %0,%1,%0\n\
+   stdcx.  %0,0,%2 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (a), "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+#define local_add_negative(a, l)   (local_add_return((a), (l)) < 0)
+
+static __inline__ long local_sub_return(long a, local_t *l)
+{
+   long t;
+
+   __asm__ __volatile__(
+"1:ldarx   %0,0,%2 # local_sub_return\n\
+   subf%0,%1,%0\n\
+   stdcx.  %0,0,%2 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (a), "r" (&(l->a.counter))
+   : "cc", "memory");
+

[PATCH 07/10] local_t : powerpc extension

2007-01-25 Thread Mathieu Desnoyers
local_t : powerpc extension

Signed-off-by: Mathieu Desnoyers [EMAIL PROTECTED]
--- a/include/asm-powerpc/local.h
+++ b/include/asm-powerpc/local.h
@@ -1 +1,342 @@
-#include asm-generic/local.h
+#ifndef _ARCH_POWERPC_LOCAL_H
+#define _ARCH_POWERPC_LOCAL_H
+
+#include linux/percpu.h
+#include asm/atomic.h
+
+typedef struct
+{
+   atomic_long_t a;
+} local_t;
+
+#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_add(i,l) atomic_long_add((i),((l)-a))
+#define local_sub(i,l) atomic_long_sub((i),((l)-a))
+#define local_inc(l)   atomic_long_inc((l)-a)
+#define local_dec(l)   atomic_long_dec((l)-a)
+
+#ifndef __powerpc64__
+
+static __inline__ int local_add_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%2 # local_add_return\n\
+   add %0,%1,%0\n
+   PPC405_ERR77(0,%2)
+  stwcx.  %0,0,%2 \n\
+   bne-1b
+   : =r (t)
+   : r (a), r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+#define local_add_negative(a, l)   (local_add_return((a), (l))  0)
+
+static __inline__ int local_sub_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%2 # local_sub_return\n\
+   subf%0,%1,%0\n
+   PPC405_ERR77(0,%2)
+  stwcx.  %0,0,%2 \n\
+   bne-1b
+   : =r (t)
+   : r (a), r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+static __inline__ int local_inc_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%1 # local_inc_return\n\
+   addic   %0,%0,1\n
+   PPC405_ERR77(0,%1)
+  stwcx.  %0,0,%1 \n\
+   bne-1b
+   : =r (t)
+   : r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+/*
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+static __inline__ int local_dec_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%1 # local_dec_return\n\
+   addic   %0,%0,-1\n
+   PPC405_ERR77(0,%1)
+  stwcx.  %0,0,%1\n\
+   bne-1b
+   : =r (t)
+   : r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+#define local_cmpxchg(l, o, n) \
+   ((long)cmpxchg(((l)-a.counter), (o), (n)))
+#define local_xchg(l, new) (xchg(((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 v...
+ * @u: ...unless v 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.
+ */
+static __inline__ int local_add_unless(local_t *l, int a, int u)
+{
+   int t;
+
+   __asm__ __volatile__ (
+1:lwarx   %0,0,%1 # local_add_unless\n\
+   cmpw0,%0,%3 \n\
+   beq-2f \n\
+   add %0,%2,%0 \n
+   PPC405_ERR77(0,%2)
+  stwcx.  %0,0,%1 \n\
+   bne-1b \n
+  subf%0,%2,%0 \n\
+2:
+   : =r (t)
+   : r ((l-a.counter)), r (a), r (u)
+   : cc, memory);
+
+   return t != u;
+}
+
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_sub_and_test(a, l)   (local_sub_return((a), (l)) == 0)
+#define local_dec_and_test(l)  (local_dec_return((l)) == 0)
+
+/*
+ * Atomically test *l and decrement if it is greater than 0.
+ * The function returns the old value of *l minus 1.
+ */
+static __inline__ int local_dec_if_positive(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%1 # local_dec_if_positive\n\
+   cmpwi   %0,1\n\
+   addi%0,%0,-1\n\
+   blt-2f\n
+   PPC405_ERR77(0,%1)
+  stwcx.  %0,0,%1\n\
+   bne-1b
+   \n\
+2:: =b (t)
+   : r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+#else /* __powerpc64__ */
+
+static __inline__ long local_add_return(long a, local_t *l)
+{
+   long t;
+
+   __asm__ __volatile__(
+1:ldarx   %0,0,%2 # local_add_return\n\
+   add %0,%1,%0\n\
+   stdcx.  %0,0,%2 \n\
+   bne-1b
+   : =r (t)
+   : r (a), r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+#define local_add_negative(a, l)   (local_add_return((a), (l))  0)
+
+static __inline__ long local_sub_return(long a, local_t *l)
+{
+   long t;
+
+   __asm__ __volatile__(
+1:ldarx   %0,0,%2 # local_sub_return\n\
+   subf%0,%1,%0\n\
+   stdcx.  %0,0,%2 \n\
+   bne-1b
+   : =r (t)
+   : r (a), r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+static __inline__ long local_inc_return(local_t *l)
+{
+   

[PATCH 07/10] local_t : powerpc extension

2007-01-11 Thread Mathieu Desnoyers
local_t : powerpc extension

Signed-off-by: Mathieu Desnoyers <[EMAIL PROTECTED]>

--- a/include/asm-powerpc/local.h
+++ b/include/asm-powerpc/local.h
@@ -1 +1,344 @@
-#include 
+#ifndef _ARCH_POWERPC_LOCAL_H
+#define _ARCH_POWERPC_LOCAL_H
+
+#include 
+#include 
+
+typedef struct
+{
+   atomic_long_t a;
+} local_t;
+
+#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_add(i,l) atomic_long_add((i),(&(l)->a))
+#define local_sub(i,l) atomic_long_sub((i),(&(l)->a))
+#define local_inc(l)   atomic_long_inc(&(l)->a)
+#define local_dec(l)   atomic_long_dec(&(l)->a)
+
+#ifndef __powerpc64__
+
+static __inline__ int local_add_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%2 # local_add_return\n\
+   add %0,%1,%0\n"
+   PPC405_ERR77(0,%2)
+"  stwcx.  %0,0,%2 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (a), "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+#define local_add_negative(a, l)   (local_add_return((a), (l)) < 0)
+
+static __inline__ int local_sub_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%2 # local_sub_return\n\
+   subf%0,%1,%0\n"
+   PPC405_ERR77(0,%2)
+"  stwcx.  %0,0,%2 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (a), "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+static __inline__ int local_inc_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%1 # local_inc_return\n\
+   addic   %0,%0,1\n"
+   PPC405_ERR77(0,%1)
+"  stwcx.  %0,0,%1 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+/*
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+static __inline__ int local_dec_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%1 # local_dec_return\n\
+   addic   %0,%0,-1\n"
+   PPC405_ERR77(0,%1)
+"  stwcx.  %0,0,%1\n\
+   bne-1b"
+   : "=" (t)
+   : "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+#define local_cmpxchg(l, o, n) \
+   ((long)cmpxchg(&((l)->a.counter), (o), (n)))
+#define local_xchg(l, new) (xchg(&((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 v...
+ * @u: ...unless v 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.
+ */
+static __inline__ int local_add_unless(local_t *l, int a, int u)
+{
+   int t;
+
+   __asm__ __volatile__ (
+"1:lwarx   %0,0,%1 # local_add_unless\n\
+   cmpw0,%0,%3 \n\
+   beq-2f \n\
+   add %0,%2,%0 \n"
+   PPC405_ERR77(0,%2)
+"  stwcx.  %0,0,%1 \n\
+   bne-1b \n"
+"  subf%0,%2,%0 \n\
+2:"
+   : "=" (t)
+   : "r" (&(l->a.counter)), "r" (a), "r" (u)
+   : "cc", "memory");
+
+   return t != u;
+}
+
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_sub_and_test(a, l)   (local_sub_return((a), (l)) == 0)
+#define local_dec_and_test(l)  (local_dec_return((l)) == 0)
+
+/*
+ * Atomically test *l and decrement if it is greater than 0.
+ * The function returns the old value of *l minus 1.
+ */
+static __inline__ int local_dec_if_positive(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+"1:lwarx   %0,0,%1 # local_dec_if_positive\n\
+   addic.  %0,%0,-1\n\
+   blt-2f\n"
+   PPC405_ERR77(0,%1)
+"  stwcx.  %0,0,%1\n\
+   bne-1b"
+   "\n\
+2:": "=" (t)
+   : "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+#else /* __powerpc64__ */
+
+static __inline__ long local_add_return(long a, local_t *l)
+{
+   long t;
+
+   __asm__ __volatile__(
+"1:ldarx   %0,0,%2 # local_add_return\n\
+   add %0,%1,%0\n\
+   stdcx.  %0,0,%2 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (a), "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+
+#define local_add_negative(a, l)   (local_add_return((a), (l)) < 0)
+
+static __inline__ long local_sub_return(long a, local_t *l)
+{
+   long t;
+
+   __asm__ __volatile__(
+"1:ldarx   %0,0,%2 # local_sub_return\n\
+   subf%0,%1,%0\n\
+   stdcx.  %0,0,%2 \n\
+   bne-1b"
+   : "=" (t)
+   : "r" (a), "r" (&(l->a.counter))
+   : "cc", "memory");
+
+   return t;
+}
+

[PATCH 07/10] local_t : powerpc extension

2007-01-11 Thread Mathieu Desnoyers
local_t : powerpc extension

Signed-off-by: Mathieu Desnoyers [EMAIL PROTECTED]

--- a/include/asm-powerpc/local.h
+++ b/include/asm-powerpc/local.h
@@ -1 +1,344 @@
-#include asm-generic/local.h
+#ifndef _ARCH_POWERPC_LOCAL_H
+#define _ARCH_POWERPC_LOCAL_H
+
+#include linux/percpu.h
+#include asm/atomic.h
+
+typedef struct
+{
+   atomic_long_t a;
+} local_t;
+
+#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_add(i,l) atomic_long_add((i),((l)-a))
+#define local_sub(i,l) atomic_long_sub((i),((l)-a))
+#define local_inc(l)   atomic_long_inc((l)-a)
+#define local_dec(l)   atomic_long_dec((l)-a)
+
+#ifndef __powerpc64__
+
+static __inline__ int local_add_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%2 # local_add_return\n\
+   add %0,%1,%0\n
+   PPC405_ERR77(0,%2)
+  stwcx.  %0,0,%2 \n\
+   bne-1b
+   : =r (t)
+   : r (a), r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+#define local_add_negative(a, l)   (local_add_return((a), (l))  0)
+
+static __inline__ int local_sub_return(int a, local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%2 # local_sub_return\n\
+   subf%0,%1,%0\n
+   PPC405_ERR77(0,%2)
+  stwcx.  %0,0,%2 \n\
+   bne-1b
+   : =r (t)
+   : r (a), r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+static __inline__ int local_inc_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%1 # local_inc_return\n\
+   addic   %0,%0,1\n
+   PPC405_ERR77(0,%1)
+  stwcx.  %0,0,%1 \n\
+   bne-1b
+   : =r (t)
+   : r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+/*
+ * local_inc_and_test - increment and test
+ * @l: pointer of type local_t
+ *
+ * Atomically increments @l by 1
+ * and returns true if the result is zero, or false for all
+ * other cases.
+ */
+#define local_inc_and_test(l) (local_inc_return(l) == 0)
+
+static __inline__ int local_dec_return(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%1 # local_dec_return\n\
+   addic   %0,%0,-1\n
+   PPC405_ERR77(0,%1)
+  stwcx.  %0,0,%1\n\
+   bne-1b
+   : =r (t)
+   : r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+#define local_cmpxchg(l, o, n) \
+   ((long)cmpxchg(((l)-a.counter), (o), (n)))
+#define local_xchg(l, new) (xchg(((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 v...
+ * @u: ...unless v 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.
+ */
+static __inline__ int local_add_unless(local_t *l, int a, int u)
+{
+   int t;
+
+   __asm__ __volatile__ (
+1:lwarx   %0,0,%1 # local_add_unless\n\
+   cmpw0,%0,%3 \n\
+   beq-2f \n\
+   add %0,%2,%0 \n
+   PPC405_ERR77(0,%2)
+  stwcx.  %0,0,%1 \n\
+   bne-1b \n
+  subf%0,%2,%0 \n\
+2:
+   : =r (t)
+   : r ((l-a.counter)), r (a), r (u)
+   : cc, memory);
+
+   return t != u;
+}
+
+#define local_inc_not_zero(l) local_add_unless((l), 1, 0)
+
+#define local_sub_and_test(a, l)   (local_sub_return((a), (l)) == 0)
+#define local_dec_and_test(l)  (local_dec_return((l)) == 0)
+
+/*
+ * Atomically test *l and decrement if it is greater than 0.
+ * The function returns the old value of *l minus 1.
+ */
+static __inline__ int local_dec_if_positive(local_t *l)
+{
+   int t;
+
+   __asm__ __volatile__(
+1:lwarx   %0,0,%1 # local_dec_if_positive\n\
+   addic.  %0,%0,-1\n\
+   blt-2f\n
+   PPC405_ERR77(0,%1)
+  stwcx.  %0,0,%1\n\
+   bne-1b
+   \n\
+2:: =r (t)
+   : r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+#else /* __powerpc64__ */
+
+static __inline__ long local_add_return(long a, local_t *l)
+{
+   long t;
+
+   __asm__ __volatile__(
+1:ldarx   %0,0,%2 # local_add_return\n\
+   add %0,%1,%0\n\
+   stdcx.  %0,0,%2 \n\
+   bne-1b
+   : =r (t)
+   : r (a), r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+#define local_add_negative(a, l)   (local_add_return((a), (l))  0)
+
+static __inline__ long local_sub_return(long a, local_t *l)
+{
+   long t;
+
+   __asm__ __volatile__(
+1:ldarx   %0,0,%2 # local_sub_return\n\
+   subf%0,%1,%0\n\
+   stdcx.  %0,0,%2 \n\
+   bne-1b
+   : =r (t)
+   : r (a), r ((l-a.counter))
+   : cc, memory);
+
+   return t;
+}
+
+static __inline__ long local_inc_return(local_t *l)
+{
+   long t;
+
+   __asm__