1 | #include "srl_lock.h" |
---|
2 | |
---|
3 | int srl_lock_lock(srl_lock_t slock ) |
---|
4 | { |
---|
5 | register int delay= rand(); |
---|
6 | |
---|
7 | asm volatile ("_locks_llsc: \n" |
---|
8 | "ll $2, 0(%0) \n" // $2 <= _locks_lock |
---|
9 | "bnez $2, _locks_delay \n" // random delay if busy |
---|
10 | "li $3, 1 \n" // prepare argument for sc |
---|
11 | "sc $3, 0(%0) \n" // try to set _locks_busy |
---|
12 | "bnez $3, _locks_ok \n" // exit if atomic |
---|
13 | "_locks_delay: \n" |
---|
14 | "move $4, %1 \n" // $4 <= delay |
---|
15 | "_locks_loop: \n" |
---|
16 | "addi $4, $4, -1 \n" // $4 <= $4 - 1 |
---|
17 | "beqz $4, _locks_loop \n" // test end delay |
---|
18 | "j _locks_llsc \n" // retry |
---|
19 | "_locks_ok: \n" |
---|
20 | ::"r"(&(slock.lock)),"r"(delay):"$2","$3","$4"); |
---|
21 | return 0; |
---|
22 | } |
---|
23 | |
---|
24 | void srl_lock_unlock( srl_lock_t slock ) |
---|
25 | { |
---|
26 | asm volatile( "sw $0, (%0)\n" |
---|
27 | "sync " |
---|
28 | ::"r"(&(slock.lock))); |
---|
29 | } |
---|
30 | |
---|
31 | int srl_lock_try_lock( srl_lock_t slock ) |
---|
32 | { |
---|
33 | register int ret = 0; |
---|
34 | asm volatile ("ll $2, 0(%1) \n" // $2 <= _locks_lock |
---|
35 | "bnez $2, _lock_done \n" // exitif busy |
---|
36 | "li $3, 1 \n" // prepare argument for sc |
---|
37 | "sc $3, 0(%1) \n" // try to set _locks_busy |
---|
38 | "add %0, $0, $3 \n" // ret(exit) value |
---|
39 | "_lock_done: \n" |
---|
40 | :"=r"(ret) |
---|
41 | :"r"(&(slock.lock)) |
---|
42 | :"$2","$3"); |
---|
43 | return ret; |
---|
44 | } |
---|
45 | |
---|
46 | |
---|