diff options
author | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-03-31 21:56:46 +0000 |
---|---|---|
committer | Kanoj Sarcar <kanoj@engr.sgi.com> | 2000-03-31 21:56:46 +0000 |
commit | 0b5270b32f95e11367268d13c2f4bc29cf7eadca (patch) | |
tree | 7b17590c04b59b2137d6e4c09b189e29414219f1 /include/asm-mips64/spinlock.h | |
parent | 202a772a88c337dc0cc1902eb56ead2894b722a5 (diff) |
spin_trylock acts on a word memory pointer, and can not use test_and_set_bit
which works on a double-word memory pointer. Wrong results ensue otherwise
due to in memory format of data (aka endianness).
Diffstat (limited to 'include/asm-mips64/spinlock.h')
-rw-r--r-- | include/asm-mips64/spinlock.h | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/include/asm-mips64/spinlock.h b/include/asm-mips64/spinlock.h index a2d269d29..9a1ccf198 100644 --- a/include/asm-mips64/spinlock.h +++ b/include/asm-mips64/spinlock.h @@ -65,7 +65,24 @@ static inline void spin_unlock(spinlock_t *lock) : "memory"); } -#define spin_trylock(lock) (!test_and_set_bit(0,(lock))) +static inline unsigned int spin_trylock(spinlock_t *lock) +{ + unsigned int temp, res; + + __asm__ __volatile__( + ".set\tnoreorder\t\t\t# spin_trylock\n\t" + "1:\tll\t%0, %1\n\t" + "or\t%2, %0, %3\n\t" + "sc\t%2, %1\n\t" + "beqz\t%2, 1b\n\t" + " and\t%2, %0, %3\n\t" + ".set\treorder" + :"=&r" (temp), "=m" (*lock), "=&r" (res) + :"r" (1), "m" (*lock) + : "memory"); + + return res == 0; +} /* * Read-write spinlocks, allowing multiple readers but only one writer. |