ref: 7f4f1776a930dc9b80f099ca869b0827bbc54383
dir: /lib/thread/mutex+plan9.myr/
use std use sys use "atomic.use" use "common.use" pkg thread = type mutex = struct _state : uint32 _sem : uint32 ;; 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) }