#include "srl_lock.h" int srl_lock_lock(srl_lock_t slock ) { register int delay= rand(); asm volatile ("_locks_llsc: \n" "ll $2, 0(%0) \n" // $2 <= _locks_lock "bnez $2, _locks_delay \n" // random delay if busy "li $3, 1 \n" // prepare argument for sc "sc $3, 0(%0) \n" // try to set _locks_busy "bnez $3, _locks_ok \n" // exit if atomic "_locks_delay: \n" "move $4, %1 \n" // $4 <= delay "_locks_loop: \n" "addi $4, $4, -1 \n" // $4 <= $4 - 1 "beqz $4, _locks_loop \n" // test end delay "j _locks_llsc \n" // retry "_locks_ok: \n" ::"r"(&(slock.lock)),"r"(delay):"$2","$3","$4"); return 0; } void srl_lock_unlock( srl_lock_t slock ) { asm volatile( "sw $0, (%0)\n" "sync " ::"r"(&(slock.lock))); } int srl_lock_try_lock( srl_lock_t slock ) { register int ret = 0; asm volatile ("ll $2, 0(%1) \n" // $2 <= _locks_lock "bnez $2, _lock_done \n" // exitif busy "li $3, 1 \n" // prepare argument for sc "sc $3, 0(%1) \n" // try to set _locks_busy "add %0, $0, $3 \n" // ret(exit) value "_lock_done: \n" :"=r"(ret) :"r"(&(slock.lock)) :"$2","$3"); return ret; }