X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=include%2Fasm-ia64%2Fspinlock.h;h=909936f25512e8ebbc3967d0eb775a12c989dd03;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=28ba9138b17f1a614d6c25d9aae745c5f14d0384;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h index 28ba9138b..909936f25 100644 --- a/include/asm-ia64/spinlock.h +++ b/include/asm-ia64/spinlock.h @@ -19,6 +19,9 @@ typedef struct { volatile unsigned int lock; +#ifdef CONFIG_PREEMPT + unsigned int break_lock; +#endif } spinlock_t; #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } @@ -32,10 +35,10 @@ typedef struct { * carefully coded to touch only those registers that spin_lock() marks "clobbered". */ -#define IA64_SPINLOCK_CLOBBERS "ar.ccv", "ar.pfs", "p14", "r28", "r29", "r30", "b6", "memory" +#define IA64_SPINLOCK_CLOBBERS "ar.ccv", "ar.pfs", "p14", "p15", "r27", "r28", "r29", "r30", "b6", "memory" static inline void -_raw_spin_lock (spinlock_t *lock) +_raw_spin_lock_flags (spinlock_t *lock, unsigned long flags) { register volatile unsigned int *ptr asm ("r31") = &lock->lock; @@ -50,9 +53,10 @@ _raw_spin_lock (spinlock_t *lock) "cmpxchg4.acq r30 = [%1], r30, ar.ccv\n\t" "movl r29 = ia64_spinlock_contention_pre3_4;;\n\t" "cmp4.ne p14, p0 = r30, r0\n\t" - "mov b6 = r29;;\n" + "mov b6 = r29;;\n\t" + "mov r27=%2\n\t" "(p14) br.cond.spnt.many b6" - : "=r"(ptr) : "r"(ptr) : IA64_SPINLOCK_CLOBBERS); + : "=r"(ptr) : "r"(ptr), "r" (flags) : IA64_SPINLOCK_CLOBBERS); # else asm volatile ("{\n\t" " mov ar.ccv = r0\n\t" @@ -60,33 +64,38 @@ _raw_spin_lock (spinlock_t *lock) " mov r30 = 1;;\n\t" "}\n\t" "cmpxchg4.acq r30 = [%1], r30, ar.ccv;;\n\t" - "cmp4.ne p14, p0 = r30, r0\n" + "cmp4.ne p14, p0 = r30, r0\n\t" + "mov r27=%2\n\t" "(p14) brl.cond.spnt.many ia64_spinlock_contention_pre3_4;;" - : "=r"(ptr) : "r"(ptr) : IA64_SPINLOCK_CLOBBERS); + : "=r"(ptr) : "r"(ptr), "r" (flags) : IA64_SPINLOCK_CLOBBERS); # endif /* CONFIG_MCKINLEY */ #else # ifdef CONFIG_ITANIUM /* don't use brl on Itanium... */ /* mis-declare, so we get the entry-point, not it's function descriptor: */ asm volatile ("mov r30 = 1\n\t" + "mov r27=%2\n\t" "mov ar.ccv = r0;;\n\t" "cmpxchg4.acq r30 = [%0], r30, ar.ccv\n\t" "movl r29 = ia64_spinlock_contention;;\n\t" "cmp4.ne p14, p0 = r30, r0\n\t" - "mov b6 = r29;;\n" + "mov b6 = r29;;\n\t" "(p14) br.call.spnt.many b6 = b6" - : "=r"(ptr) : "r"(ptr) : IA64_SPINLOCK_CLOBBERS); + : "=r"(ptr) : "r"(ptr), "r" (flags) : IA64_SPINLOCK_CLOBBERS); # else asm volatile ("mov r30 = 1\n\t" + "mov r27=%2\n\t" "mov ar.ccv = r0;;\n\t" "cmpxchg4.acq r30 = [%0], r30, ar.ccv;;\n\t" "cmp4.ne p14, p0 = r30, r0\n\t" "(p14) brl.call.spnt.many b6=ia64_spinlock_contention;;" - : "=r"(ptr) : "r"(ptr) : IA64_SPINLOCK_CLOBBERS); + : "=r"(ptr) : "r"(ptr), "r" (flags) : IA64_SPINLOCK_CLOBBERS); # endif /* CONFIG_MCKINLEY */ #endif } +#define _raw_spin_lock(lock) _raw_spin_lock_flags(lock, 0) #else /* !ASM_SUPPORTED */ +#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) # define _raw_spin_lock(x) \ do { \ __u32 *ia64_spinlock_ptr = (__u32 *) (x); \ @@ -108,13 +117,17 @@ do { \ #define spin_unlock_wait(x) do { barrier(); } while ((x)->lock) typedef struct { - volatile int read_counter : 31; - volatile int write_lock : 1; + volatile unsigned int read_counter : 31; + volatile unsigned int write_lock : 1; +#ifdef CONFIG_PREEMPT + unsigned int break_lock; +#endif } rwlock_t; #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 } #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0) -#define rwlock_is_locked(x) (*(volatile int *) (x) != 0) +#define read_can_lock(rw) (*(volatile int *)(rw) >= 0) +#define write_can_lock(rw) (*(volatile int *)(rw) == 0) #define _raw_read_lock(rw) \ do { \ @@ -184,6 +197,8 @@ do { \ #endif /* !ASM_SUPPORTED */ +#define _raw_read_trylock(lock) generic_raw_read_trylock(lock) + #define _raw_write_unlock(x) \ ({ \ smp_mb__before_clear_bit(); /* need barrier before releasing lock... */ \