[PATCH] Directed yield: cpu_relax variants for spinlocks and rw-locks
[linux-2.6.git] / include / asm-sparc64 / spinlock.h
index ec85d12d73b98a353e0fdcaf346489b09f80839a..0006fe9f8c7a03cab556cec5119ad5c016608e74 100644 (file)
@@ -6,7 +6,6 @@
 #ifndef __SPARC64_SPINLOCK_H
 #define __SPARC64_SPINLOCK_H
 
-#include <linux/config.h>
 #include <linux/threads.h>     /* For NR_CPUS */
 
 #ifndef __ASSEMBLY__
@@ -131,6 +130,28 @@ static void inline __read_lock(raw_rwlock_t *lock)
        : "memory");
 }
 
+static int inline __read_trylock(raw_rwlock_t *lock)
+{
+       int tmp1, tmp2;
+
+       __asm__ __volatile__ (
+"1:    ldsw            [%2], %0\n"
+"      brlz,a,pn       %0, 2f\n"
+"       mov            0, %0\n"
+"      add             %0, 1, %1\n"
+"      cas             [%2], %0, %1\n"
+"      cmp             %0, %1\n"
+"      membar          #StoreLoad | #StoreStore\n"
+"      bne,pn          %%icc, 1b\n"
+"       mov            1, %0\n"
+"2:"
+       : "=&r" (tmp1), "=&r" (tmp2)
+       : "r" (lock)
+       : "memory");
+
+       return tmp1;
+}
+
 static void inline __read_unlock(raw_rwlock_t *lock)
 {
        unsigned long tmp1, tmp2;
@@ -211,15 +232,19 @@ static int inline __write_trylock(raw_rwlock_t *lock)
 }
 
 #define __raw_read_lock(p)     __read_lock(p)
+#define __raw_read_trylock(p)  __read_trylock(p)
 #define __raw_read_unlock(p)   __read_unlock(p)
 #define __raw_write_lock(p)    __write_lock(p)
 #define __raw_write_unlock(p)  __write_unlock(p)
 #define __raw_write_trylock(p) __write_trylock(p)
 
-#define __raw_read_trylock(lock)       generic__raw_read_trylock(lock)
 #define __raw_read_can_lock(rw)                (!((rw)->lock & 0x80000000UL))
 #define __raw_write_can_lock(rw)       (!(rw)->lock)
 
+#define _raw_spin_relax(lock)  cpu_relax()
+#define _raw_read_relax(lock)  cpu_relax()
+#define _raw_write_relax(lock) cpu_relax()
+
 #endif /* !(__ASSEMBLY__) */
 
 #endif /* !(__SPARC64_SPINLOCK_H) */