internal override void DoJob(ref Worker wr, Cont <Unit> uK) { Spin: var state = this.State; if (state > Initial) { goto Signaled; } if (state < Initial) { goto Spin; } if (Initial != Interlocked.CompareExchange(ref this.State, ~state, state)) { goto Spin; } WaitQueue.AddTaker(ref this.Takers, uK); this.State = Initial; return; Signaled: Work.Do(uK, ref wr); }
internal static void Signal(ref Worker wr, Nack nk) { Spin: var state = nk.State; if (state < Delayed) { goto Spin; } if (Running != Interlocked.CompareExchange(ref nk.State, state + 1, state)) { goto Spin; } WaitQueue.PickReaders(ref nk.Readers, null, ref wr); }
internal override void TryAlt(ref Worker wr, int i, Cont <Unit> uK, Else uE) { var pkSelf = uE.pk; Spin: var state = this.State; if (state > Initial) { goto TryPick; } if (state < Initial) { goto Spin; } if (Initial != Interlocked.CompareExchange(ref this.State, ~state, state)) { goto Spin; } WaitQueue.AddTaker(ref this.Takers, i, pkSelf, uK); this.State = Initial; uE.TryElse(ref wr, i + 1); return; TryPick: var st = Pick.TryPick(pkSelf); if (st > 0) { goto AlreadyPicked; } if (st < 0) { goto TryPick; } Pick.SetNacks(ref wr, i, pkSelf); Work.Do(uK, ref wr); AlreadyPicked: return; }
/// <summary>Internal implementation detail.</summary> internal override void TryAlt(ref Worker wr, int i, Pick pkSelf, Cont <Unit> uK) { Spin: var state = this.State; if (state > Initial) { goto TryPick; } if (state < Initial) { goto Spin; } if (Initial != Interlocked.CompareExchange(ref this.State, Locked, Initial)) { goto Spin; } WaitQueue.AddTaker(ref this.Takers, i, pkSelf, uK); this.State = Initial; uK.TryNext(ref wr, i + 1, pkSelf); return; TryPick: var st = Pick.TryPick(pkSelf); if (st > 0) { goto AlreadyPicked; } if (st < 0) { goto TryPick; } Pick.SetNacks(ref wr, i, pkSelf); uK.DoCont(ref wr, null); AlreadyPicked: return; }