164 строки
2.7 KiB
ArmAsm
164 строки
2.7 KiB
ArmAsm
/* rwsem.S: RW semaphore assembler.
|
|
*
|
|
* Written by David S. Miller (davem@redhat.com), 2001.
|
|
* Derived from asm-i386/rwsem.h
|
|
*/
|
|
|
|
#include <asm/rwsem-const.h>
|
|
|
|
.section .sched.text, "ax"
|
|
|
|
.globl __down_read
|
|
__down_read:
|
|
1: lduw [%o0], %g1
|
|
add %g1, 1, %g7
|
|
cas [%o0], %g1, %g7
|
|
cmp %g1, %g7
|
|
bne,pn %icc, 1b
|
|
add %g7, 1, %g7
|
|
cmp %g7, 0
|
|
bl,pn %icc, 3f
|
|
nop
|
|
2:
|
|
retl
|
|
nop
|
|
3:
|
|
save %sp, -192, %sp
|
|
call rwsem_down_read_failed
|
|
mov %i0, %o0
|
|
ret
|
|
restore
|
|
.size __down_read, .-__down_read
|
|
|
|
.globl __down_read_trylock
|
|
__down_read_trylock:
|
|
1: lduw [%o0], %g1
|
|
add %g1, 1, %g7
|
|
cmp %g7, 0
|
|
bl,pn %icc, 2f
|
|
mov 0, %o1
|
|
cas [%o0], %g1, %g7
|
|
cmp %g1, %g7
|
|
bne,pn %icc, 1b
|
|
mov 1, %o1
|
|
2: retl
|
|
mov %o1, %o0
|
|
.size __down_read_trylock, .-__down_read_trylock
|
|
|
|
.globl __down_write
|
|
__down_write:
|
|
sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
|
|
or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
|
|
1:
|
|
lduw [%o0], %g3
|
|
add %g3, %g1, %g7
|
|
cas [%o0], %g3, %g7
|
|
cmp %g3, %g7
|
|
bne,pn %icc, 1b
|
|
cmp %g7, 0
|
|
bne,pn %icc, 3f
|
|
nop
|
|
2: retl
|
|
nop
|
|
3:
|
|
save %sp, -192, %sp
|
|
call rwsem_down_write_failed
|
|
mov %i0, %o0
|
|
ret
|
|
restore
|
|
.size __down_write, .-__down_write
|
|
|
|
.globl __down_write_trylock
|
|
__down_write_trylock:
|
|
sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
|
|
or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
|
|
1:
|
|
lduw [%o0], %g3
|
|
cmp %g3, 0
|
|
bne,pn %icc, 2f
|
|
mov 0, %o1
|
|
add %g3, %g1, %g7
|
|
cas [%o0], %g3, %g7
|
|
cmp %g3, %g7
|
|
bne,pn %icc, 1b
|
|
mov 1, %o1
|
|
2: retl
|
|
mov %o1, %o0
|
|
.size __down_write_trylock, .-__down_write_trylock
|
|
|
|
.globl __up_read
|
|
__up_read:
|
|
1:
|
|
lduw [%o0], %g1
|
|
sub %g1, 1, %g7
|
|
cas [%o0], %g1, %g7
|
|
cmp %g1, %g7
|
|
bne,pn %icc, 1b
|
|
cmp %g7, 0
|
|
bl,pn %icc, 3f
|
|
nop
|
|
2: retl
|
|
nop
|
|
3: sethi %hi(RWSEM_ACTIVE_MASK), %g1
|
|
sub %g7, 1, %g7
|
|
or %g1, %lo(RWSEM_ACTIVE_MASK), %g1
|
|
andcc %g7, %g1, %g0
|
|
bne,pn %icc, 2b
|
|
nop
|
|
save %sp, -192, %sp
|
|
call rwsem_wake
|
|
mov %i0, %o0
|
|
ret
|
|
restore
|
|
.size __up_read, .-__up_read
|
|
|
|
.globl __up_write
|
|
__up_write:
|
|
sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
|
|
or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
|
|
1:
|
|
lduw [%o0], %g3
|
|
sub %g3, %g1, %g7
|
|
cas [%o0], %g3, %g7
|
|
cmp %g3, %g7
|
|
bne,pn %icc, 1b
|
|
sub %g7, %g1, %g7
|
|
cmp %g7, 0
|
|
bl,pn %icc, 3f
|
|
nop
|
|
2:
|
|
retl
|
|
nop
|
|
3:
|
|
save %sp, -192, %sp
|
|
call rwsem_wake
|
|
mov %i0, %o0
|
|
ret
|
|
restore
|
|
.size __up_write, .-__up_write
|
|
|
|
.globl __downgrade_write
|
|
__downgrade_write:
|
|
sethi %hi(RWSEM_WAITING_BIAS), %g1
|
|
or %g1, %lo(RWSEM_WAITING_BIAS), %g1
|
|
1:
|
|
lduw [%o0], %g3
|
|
sub %g3, %g1, %g7
|
|
cas [%o0], %g3, %g7
|
|
cmp %g3, %g7
|
|
bne,pn %icc, 1b
|
|
sub %g7, %g1, %g7
|
|
cmp %g7, 0
|
|
bl,pn %icc, 3f
|
|
nop
|
|
2:
|
|
retl
|
|
nop
|
|
3:
|
|
save %sp, -192, %sp
|
|
call rwsem_downgrade_wake
|
|
mov %i0, %o0
|
|
ret
|
|
restore
|
|
.size __downgrade_write, .-__downgrade_write
|