dec_and_lock.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:1k
- /* $Id: dec_and_lock.S,v 1.5 2001/11/18 00:12:56 davem Exp $
- * 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)
- */
- #include <linux/config.h>
- #ifndef CONFIG_DEBUG_SPINLOCK
- .text
- .align 64
- /* CAS basically works like this:
- *
- * void CAS(MEM, REG1, REG2)
- * {
- * START_ATOMIC();
- * if (*(MEM) == REG1) {
- * TMP = *(MEM);
- * *(MEM) = REG2;
- * REG2 = TMP;
- * } else
- * REG2 = *(MEM);
- * END_ATOMIC();
- * }
- */
- .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:
- membar #StoreLoad | #StoreStore
- 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) */
- cmp %g5, %g7
- be,pt %icc, 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
- ba,pt %xcc, to_zero
- nop
- nop
- #endif /* !(CONFIG_DEBUG_SPINLOCK) */