ref: 74d91a0021de012908cfdb35fb61a1473a376130
dir: /lib/thread/mutex+plan9.myr/
use std use sys use "atomic" pkg thread = type mutex = struct _state : int32 _sem : int32 ;; const mkmtx : (-> mutex) const mtxlock : (mtx : mutex# -> void) const mtxtrylock : (mtx : mutex# -> bool) const mtxunlock : (mtx : mutex# -> void) ;; const mkmtx = { -> [._state = 0, ._sem=0] } const mtxlock = {mtx /* if the old value was 0, we aren't contended */ if xadd(&mtx._state, 1) == 0 -> void ;; while sys.semacquire(&mtx._sem, 1) < 0 /* interrupted; retry */ ;; } const mtxtrylock = {mtx -> xcas(&mtx._state, 0, 1) == 0 } const mtxunlock = {mtx /* if we were the only thread waiting on the lock, there was no contention */ if xadd(&mtx._state, -1) == 1 -> void ;; sys.semrelease(&mtx._sem, 1) }