X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Fasm-ppc%2Fspinlock.h;h=909199aae1047f2baf6934e384bd0918eb3f855e;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=3e3c2a5019293bdeaa5ad4658fcd804142fa2dc7;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/include/asm-ppc/spinlock.h b/include/asm-ppc/spinlock.h index 3e3c2a501..909199aae 100644 --- a/include/asm-ppc/spinlock.h +++ b/include/asm-ppc/spinlock.h @@ -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