internal Nack(Nack next, int i0) { this.State = Running; this.Next = next; this.I0 = i0; this.I1 = Int32.MaxValue; }
internal static Nack AddNack(Pick pk, int i0) { TryClaim: var state = pk.State; if (state > 0) { goto AlreadyPicked; } if (state < 0) { goto TryClaim; } if (0 != Interlocked.CompareExchange(ref pk.State, ~state, state)) { goto TryClaim; } var nk = new Nack(pk.Nacks, i0); pk.Nacks = nk; return(nk); // Leaves the pick claimed on purpose! AlreadyPicked: return(null); }
internal static void SetNacks(ref Worker wr, int i, Pick pk) { Nack nk = pk.Nacks; if (null != nk) { SetNacks(ref wr, i, nk); } }
private static void SetNacks(ref Worker wr, int i, Nack nk) { do { if (i < nk.I0 || nk.I1 <= i) { Nack.Signal(ref wr, nk); } nk = nk.Next; } while (null != nk); }
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); }
public static Nack AddNack(Pick pk, int i0) { TryClaim: var st = TryClaim(pk); if (st > 0) { goto AlreadyPicked; } if (st < 0) { goto TryClaim; } var nk = new Nack(pk.Nacks, i0); pk.Nacks = nk; Unclaim(pk); return(nk); AlreadyPicked: return(null); }
internal static void Signal(ref Worker wr, Nack nk) { Spin: var state = nk.State; if (state > Initial) { goto JustExit; // XXX Can this happen? } if (state < Initial) { goto Spin; } if (Initial != Interlocked.CompareExchange(ref nk.State, state + 1, state)) { goto Spin; } var takers = nk.Takers; if (null == takers) { goto JustExit; } nk.Takers = null; var me = 0; Work cursor = takers; TryTaker: var taker = cursor as Cont <Unit>; cursor = cursor.Next; var pk = taker.GetPick(ref me); if (null == pk) { goto GotTaker; } TryPick: var st = Pick.TryPick(pk); if (st > 0) { goto TryNextTaker; } if (st < 0) { goto TryPick; } Pick.SetNacks(ref wr, me, pk); GotTaker: Worker.Push(ref wr, taker); TryNextTaker: if (cursor != takers) { goto TryTaker; } JustExit: return; }