}
}
+int _do_write_trylock (rwlock_t *rw, char *str)
+{
+ unsigned long caller, val;
+ int stuck = INIT_STUCK;
+ int cpu = smp_processor_id();
+ int shown = 0;
+
+ GET_CALLER(caller);
+
+ /* Try to acuire the write bit. */
+ __asm__ __volatile__(
+" mov 1, %%g3\n"
+" sllx %%g3, 63, %%g3\n"
+" ldx [%0], %%g5\n"
+" brlz,pn %%g5, 1f\n"
+" or %%g5, %%g3, %%g7\n"
+" casx [%0], %%g5, %%g7\n"
+" membar #StoreLoad | #StoreStore\n"
+" ba,pt %%xcc, 2f\n"
+" sub %%g5, %%g7, %0\n"
+"1: mov 1, %0\n"
+"2:" : "=r" (val)
+ : "0" (&(rw->lock))
+ : "g3", "g5", "g7", "memory");
+
+ if (val)
+ return 0;
+
+ if ((rw->lock & ((1UL<<63)-1UL)) != 0UL) {
+ /* Readers still around, drop the write
+ * lock, return failure.
+ */
+ __asm__ __volatile__(
+" mov 1, %%g3\n"
+" sllx %%g3, 63, %%g3\n"
+"1: ldx [%0], %%g5\n"
+" andn %%g5, %%g3, %%g7\n"
+" casx [%0], %%g5, %%g7\n"
+" cmp %%g5, %%g7\n"
+" bne,pn %%xcc, 1b\n"
+" membar #StoreLoad | #StoreStore"
+ : /* no outputs */
+ : "r" (&(rw->lock))
+ : "g3", "g5", "g7", "cc", "memory");
+
+ return 0;
+ }
+
+ /* We have it, say who we are. */
+ rw->writer_pc = ((unsigned int)caller);
+ rw->writer_cpu = cpu;
+ current->thread.smp_lock_count++;
+ current->thread.smp_lock_pc = ((unsigned int)caller);
+
+ return 1;
+}
+
#endif /* CONFIG_SMP */
extern void _do_read_unlock(rwlock_t *rw, char *str);
extern void _do_write_lock(rwlock_t *rw, char *str);
extern void _do_write_unlock(rwlock_t *rw);
+extern int _do_write_trylock(rwlock_t *rw, char *str);
#define _raw_read_lock(lock) \
do { unsigned long flags; \
local_irq_restore(flags); \
} while(0)
+#define _raw_write_trylock(lock) \
+({ unsigned long flags; \
+ int val; \
+ local_irq_save(flags); \
+ val = _do_write_trylock(lock, "write_trylock"); \
+ local_irq_restore(flags); \
+ val; \
+})
+
#endif /* CONFIG_DEBUG_SPINLOCK */
#endif /* !(__ASSEMBLY__) */