internal override void DoJob(ref Worker wr, Cont <Y> yK) { var tM = this.tM; Spin: var state = tM.State; if (state == MVar.Locked) { goto Spin; } if (state != Interlocked.CompareExchange(ref tM.State, MVar.Locked, state)) { goto Spin; } if (state <= MVar.Empty) { goto EmptyOrDemand; } var t = tM.Value; tM.State = MVar.Empty; MVarTryModifyFunCont <T, Y> .Do(this, yK, ref wr, t); return; EmptyOrDemand: WaitQueue.AddTaker(ref tM.Takers, new MVarTryModifyFunCont <T, Y>(this, yK)); tM.State = MVar.Demand; }
internal override void TryAlt(ref Worker wr, int i, Cont <Y> yK, Else tE) { var tM = this.tM; var pkSelf = tE.pk; Spin: var state = tM.State; if (state == MVar.Locked) { goto Spin; } if (state != Interlocked.CompareExchange(ref tM.State, MVar.Locked, state)) { goto Spin; } if (state <= MVar.Empty) { goto EmptyOrDemand; } TryPick: var stSelf = Pick.TryPick(pkSelf); if (stSelf > 0) { goto AlreadyPicked; } if (stSelf < 0) { goto TryPick; } Pick.SetNacks(ref wr, i, pkSelf); var t = tM.Value; tM.State = MVar.Empty; MVarTryModifyFunCont <T, Y> .Do(this, yK, ref wr, t); return; AlreadyPicked: tM.State = MVar.Full; return; EmptyOrDemand: WaitQueue.AddTaker(ref tM.Takers, i, pkSelf, new MVarTryModifyFunCont <T, Y>(this, yK)); tM.State = MVar.Demand; tE.TryElse(ref wr, i + 1); return; }