" strex ip, lr, [%0]\n" \
" teq ip, #0\n" \
" bne 1b\n" \
-" teq lr, #0\n" \
+" cmp lr, #0\n" \
" movle ip, %0\n" \
" blle " #wake \
: \
__asm__ __volatile__( \
"@ up_op_read\n" \
"1: ldrex lr, [%0]\n" \
-" add lr, lr, %1\n" \
+" adds lr, lr, %1\n" \
" strex ip, lr, [%0]\n" \
" teq ip, #0\n" \
" bne 1b\n" \
} rwlock_t;
#define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
-#define rwlock_init(x) do { *(x) + RW_LOCK_UNLOCKED; } while (0)
+#define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while (0)
+#define rwlock_is_locked(x) (*((volatile unsigned int *)(x)) != 0)
/*
* Write locks are easy - we just set bit 31. When unlocking, we can
: "cc", "memory");
}
+static inline int _raw_write_trylock(rwlock_t *rw)
+{
+ unsigned long tmp;
+
+ __asm__ __volatile__(
+"1: ldrex %0, [%1]\n"
+" teq %0, #0\n"
+" strexeq %0, %2, [%1]"
+ : "=&r" (tmp)
+ : "r" (&rw->lock), "r" (0x80000000)
+ : "cc", "memory");
+
+ return tmp == 0;
+}
+
static inline void _raw_write_unlock(rwlock_t *rw)
{
__asm__ __volatile__(
static inline void _raw_read_unlock(rwlock_t *rw)
{
+ unsigned long tmp, tmp2;
+
__asm__ __volatile__(
"1: ldrex %0, [%2]\n"
" sub %0, %0, #1\n"
#define _raw_read_trylock(lock) generic_raw_read_trylock(lock)
-static inline int _raw_write_trylock(rwlock_t *rw)
-{
- unsigned long tmp;
-
- __asm__ __volatile__(
-"1: ldrex %0, [%1]\n"
-" teq %0, #0\n"
-" strexeq %0, %2, [%1]"
- : "=&r" (tmp)
- : "r" (&rw->lock), "r" (0x80000000)
- : "cc", "memory");
-
- return tmp == 0;
-}
-
#endif /* __ASM_SPINLOCK_H */