This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / arch / sparc64 / lib / debuglocks.c
index 341cce7..7b68a4d 100644 (file)
@@ -299,4 +299,59 @@ wlock_again:
        }
 }
 
+int _do_write_trylock (rwlock_t *rw, char *str)
+{
+       unsigned long caller, val;
+       int cpu = smp_processor_id();
+
+       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 */