예제 #1
0
 internal Nack(Nack next, int i0)
 {
     this.State = Running;
     this.Next  = next;
     this.I0    = i0;
     this.I1    = Int32.MaxValue;
 }
예제 #2
0
파일: Pick.cs 프로젝트: kolektiv/Hopac
        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);
        }
예제 #3
0
파일: Pick.cs 프로젝트: silky/Hopac
        internal static void SetNacks(ref Worker wr, int i, Pick pk)
        {
            Nack nk = pk.Nacks;

            if (null != nk)
            {
                SetNacks(ref wr, i, nk);
            }
        }
예제 #4
0
파일: Pick.cs 프로젝트: kolektiv/Hopac
 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);
 }
예제 #5
0
        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);
        }
예제 #6
0
파일: Pick.cs 프로젝트: silky/Hopac
        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);
        }
예제 #7
0
        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;
        }