mtype = { Wakeme, Running }; bit lk, sleep_q; bit r_lock, r_want; mtype State = Running; active proctype client() { sleep: /* sleep routine */ atomic { (lk == 0) -> lk = 1 }; /* spinlock(&lk) */ do /* while r->lock */ :: (r_lock == 1) -> /* r->lock == 1 */ r_want = 1; State = Wakeme; lk = 0; /* freelock(&lk) */ (State == Running); /* wait for wakeup */ :: else -> /* r->lock == 0 */ break od; progress: assert(r_lock == 0); /* should still be true */ r_lock = 1; /* consumed resource */ lk = 0; /* freelock(&lk) */ goto sleep } active proctype server() /* interrupt routine */ { wakeup: /* wakeup routine */ r_lock = 0; /* r->lock = 0 */ (lk == 0); /* waitlock(&lk) */ if :: r_want -> /* someone is sleeping */ atomic { /* spinlock on sleep queue */ (sleep_q == 0) -> sleep_q = 1 }; r_want = 0; #ifdef PROPOSED_FIX (lk == 0); /* waitlock(&lk) */ #endif if :: (State == Wakeme) -> State = Running; :: else -> fi; sleep_q = 0 :: else -> fi; goto wakeup }