summaryrefslogtreecommitdiffstats
path: root/include/asm-mips64/spinlock.h
diff options
context:
space:
mode:
authorKanoj Sarcar <kanoj@engr.sgi.com>2000-03-31 21:56:46 +0000
committerKanoj Sarcar <kanoj@engr.sgi.com>2000-03-31 21:56:46 +0000
commit0b5270b32f95e11367268d13c2f4bc29cf7eadca (patch)
tree7b17590c04b59b2137d6e4c09b189e29414219f1 /include/asm-mips64/spinlock.h
parent202a772a88c337dc0cc1902eb56ead2894b722a5 (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.h19
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.