vserver 1.9.5.x5
[linux-2.6.git] / include / asm-ppc / spinlock.h
index 3e3c2a5..909199a 100644 (file)
@@ -13,6 +13,9 @@ typedef struct {
        volatile unsigned long owner_pc;
        volatile unsigned long owner_cpu;
 #endif
+#ifdef CONFIG_PREEMPT
+       unsigned int break_lock;
+#endif
 } spinlock_t;
 
 #ifdef __KERNEL__
@@ -27,6 +30,7 @@ typedef struct {
 #define spin_lock_init(x)      do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
 #define spin_is_locked(x)      ((x)->lock != 0)
 #define spin_unlock_wait(x)    do { barrier(); } while(spin_is_locked(x))
+#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
 
 #ifndef CONFIG_DEBUG_SPINLOCK
 
@@ -64,7 +68,6 @@ static inline void _raw_spin_unlock(spinlock_t *lock)
 extern void _raw_spin_lock(spinlock_t *lock);
 extern void _raw_spin_unlock(spinlock_t *lock);
 extern int _raw_spin_trylock(spinlock_t *lock);
-extern unsigned long __spin_trylock(volatile unsigned long *lock);
 
 #endif
 
@@ -79,28 +82,43 @@ extern unsigned long __spin_trylock(volatile unsigned long *lock);
  * read-locks.
  */
 typedef struct {
-       volatile unsigned long lock;
-#ifdef CONFIG_DEBUG_SPINLOCK
-       volatile unsigned long owner_pc;
+       volatile signed int lock;
+#ifdef CONFIG_PREEMPT
+       unsigned int break_lock;
 #endif
 } rwlock_t;
 
-#ifdef CONFIG_DEBUG_SPINLOCK
-#define RWLOCK_DEBUG_INIT     , 0
-#else
-#define RWLOCK_DEBUG_INIT     /* */
-#endif
-
-#define RW_LOCK_UNLOCKED (rwlock_t) { 0 RWLOCK_DEBUG_INIT }
+#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
 #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0)
 
-#define rwlock_is_locked(x)    ((x)->lock != 0)
+#define read_can_lock(rw)      ((rw)->lock >= 0)
+#define write_can_lock(rw)     (!(rw)->lock)
 
 #ifndef CONFIG_DEBUG_SPINLOCK
 
+static __inline__ int _raw_read_trylock(rwlock_t *rw)
+{
+       signed int tmp;
+
+       __asm__ __volatile__(
+"2:    lwarx   %0,0,%1         # read_trylock\n\
+       addic.  %0,%0,1\n\
+       ble-    1f\n"
+       PPC405_ERR77(0,%1)
+"      stwcx.  %0,0,%1\n\
+       bne-    2b\n\
+       isync\n\
+1:"
+       : "=&r"(tmp)
+       : "r"(&rw->lock)
+       : "cr0", "memory");
+
+       return tmp > 0;
+}
+
 static __inline__ void _raw_read_lock(rwlock_t *rw)
 {
-       unsigned int tmp;
+       signed int tmp;
 
        __asm__ __volatile__(
        "b      2f              # read_lock\n\
@@ -121,7 +139,7 @@ static __inline__ void _raw_read_lock(rwlock_t *rw)
 
 static __inline__ void _raw_read_unlock(rwlock_t *rw)
 {
-       unsigned int tmp;
+       signed int tmp;
 
        __asm__ __volatile__(
        "eieio                  # read_unlock\n\
@@ -135,9 +153,29 @@ static __inline__ void _raw_read_unlock(rwlock_t *rw)
        : "cr0", "memory");
 }
 
+static __inline__ int _raw_write_trylock(rwlock_t *rw)
+{
+       signed int tmp;
+
+       __asm__ __volatile__(
+"2:    lwarx   %0,0,%1         # write_trylock\n\
+       cmpwi   0,%0,0\n\
+       bne-    1f\n"
+       PPC405_ERR77(0,%1)
+"      stwcx.  %2,0,%1\n\
+       bne-    2b\n\
+       isync\n\
+1:"
+       : "=&r"(tmp)
+       : "r"(&rw->lock), "r"(-1)
+       : "cr0", "memory");
+
+       return tmp == 0;
+}
+
 static __inline__ void _raw_write_lock(rwlock_t *rw)
 {
-       unsigned int tmp;
+       signed int tmp;
 
        __asm__ __volatile__(
        "b      2f              # write_lock\n\
@@ -168,6 +206,8 @@ extern void _raw_read_lock(rwlock_t *rw);
 extern void _raw_read_unlock(rwlock_t *rw);
 extern void _raw_write_lock(rwlock_t *rw);
 extern void _raw_write_unlock(rwlock_t *rw);
+extern int _raw_read_trylock(rwlock_t *rw);
+extern int _raw_write_trylock(rwlock_t *rw);
 
 #endif