patch-2.4.0-test3 linux/arch/sparc64/lib/dec_and_lock.S
Next file: linux/arch/sparc64/mm/modutil.c
Previous file: linux/arch/sparc64/lib/Makefile
Back to the patch index
Back to the overall index
- Lines: 62
- Date:
Sun Jul 9 22:30:37 2000
- Orig file:
v2.4.0-test2/linux/arch/sparc64/lib/dec_and_lock.S
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.4.0-test2/linux/arch/sparc64/lib/dec_and_lock.S linux/arch/sparc64/lib/dec_and_lock.S
@@ -0,0 +1,61 @@
+/* $Id$
+ * dec_and_lock.S: Sparc64 version of "atomic_dec_and_lock()"
+ * using cas and ldstub instructions.
+ *
+ * Copyright (C) 2000 David S. Miller (davem@redhat.com)
+ */
+
+ .text
+ .align 64
+
+ /* CAS basically works like this:
+ *
+ * void CAS(MEM, REG1, REG2)
+ * {
+ * START_ATOMIC();
+ * if (*(MEM) == REG1) {
+ * TMP = *(MEM);
+ * *(MEM) = REG2;
+ * REG2 = TMP;
+ * }
+ * END_ATOMIC();
+ * }
+ *
+ * All non-contention cases are handled in 2 I-cache
+ * lines which is 1 L2 cache line.
+ */
+
+ .globl atomic_dec_and_lock
+atomic_dec_and_lock: /* %o0 = counter, %o1 = lock */
+loop1: lduw [%o0], %g5
+ subcc %g5, 1, %g7
+ be,pn %icc, to_zero
+ nop
+nzero: cas [%o0], %g5, %g7
+ cmp %g5, %g7
+ bne,pn %icc, loop1
+ mov 0, %g1
+
+out: retl
+ mov %g1, %o0
+to_zero:ldstub [%o1], %g3
+ brnz,pn %g3, spin_on_lock
+ membar #StoreLoad | #StoreStore
+loop2: cas [%o0], %g5, %g7 /* ASSERT(g7 == 0) */
+ brnz,pt %g7, out
+ mov 1, %g1
+
+ lduw [%o0], %g5
+ subcc %g5, 1, %g7
+ be,pn %icc, loop2
+ nop
+ membar #StoreStore | #LoadStore
+ stb %g0, [%o1]
+ b,pt %xcc, nzero
+ nop
+
+spin_on_lock:
+ ldub [%o1], %g3
+ brnz,pt %g3, spin_on_lock
+ membar #LoadLoad
+ b,a,pt %xcc, to_zero
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)