|
@@ -105,8 +105,8 @@ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
|
|
|
asm volatile("# beginning down_write\n\t"
|
|
|
LOCK_PREFIX " xadd %1,(%2)\n\t"
|
|
|
/* adds 0xffff0001, returns the old value */
|
|
|
- " test %1,%1\n\t"
|
|
|
- /* was the count 0 before? */
|
|
|
+ " test " __ASM_SEL(%w1,%k1) "," __ASM_SEL(%w1,%k1) "\n\t"
|
|
|
+ /* was the active mask 0 before? */
|
|
|
" jz 1f\n"
|
|
|
" call call_rwsem_down_write_failed\n"
|
|
|
"1:\n"
|
|
@@ -126,11 +126,25 @@ static inline void __down_write(struct rw_semaphore *sem)
|
|
|
*/
|
|
|
static inline int __down_write_trylock(struct rw_semaphore *sem)
|
|
|
{
|
|
|
- long ret = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
|
|
|
- RWSEM_ACTIVE_WRITE_BIAS);
|
|
|
- if (ret == RWSEM_UNLOCKED_VALUE)
|
|
|
- return 1;
|
|
|
- return 0;
|
|
|
+ long result, tmp;
|
|
|
+ asm volatile("# beginning __down_write_trylock\n\t"
|
|
|
+ " mov %0,%1\n\t"
|
|
|
+ "1:\n\t"
|
|
|
+ " test " __ASM_SEL(%w1,%k1) "," __ASM_SEL(%w1,%k1) "\n\t"
|
|
|
+ /* was the active mask 0 before? */
|
|
|
+ " jnz 2f\n\t"
|
|
|
+ " mov %1,%2\n\t"
|
|
|
+ " add %3,%2\n\t"
|
|
|
+ LOCK_PREFIX " cmpxchg %2,%0\n\t"
|
|
|
+ " jnz 1b\n\t"
|
|
|
+ "2:\n\t"
|
|
|
+ " sete %b1\n\t"
|
|
|
+ " movzbl %b1, %k1\n\t"
|
|
|
+ "# ending __down_write_trylock\n\t"
|
|
|
+ : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
|
|
|
+ : "er" (RWSEM_ACTIVE_WRITE_BIAS)
|
|
|
+ : "memory", "cc");
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
/*
|