Beispiel #1
0
            internal override void DoJob(ref Worker wr, Cont <bool> bK)
            {
                var ch = this.Ch;

TryNextTaker:
                ch.Lock.Enter();
                var tail = ch.Takers;

                if (null != tail)
                {
                    goto TryTaker;
                }
                ch.Lock.Exit();
                Cont.Do(bK, ref wr, false);
                return;

TryTaker:
                var cursor = tail.Next;

                if (tail == cursor)
                {
                    ch.Takers = null;
                    ch.Lock.Exit();
                }
                else
                {
                    tail.Next = cursor.Next;
                    ch.Lock.Exit();
                    tail = cursor as Cont <T>;
                }

                var taker = tail as Taker <T>;

                if (null == taker)
                {
                    goto GotTaker;
                }
                var pkOther = taker.Pick;

TryPickOther:
                var stOther = Pick.TryPick(pkOther);

                if (stOther > 0)
                {
                    goto TryNextTaker;
                }
                if (stOther < 0)
                {
                    goto TryPickOther;
                }

                Pick.SetNacks(ref wr, taker.Me, pkOther);

                tail = taker.Cont;
GotTaker:
                tail.Value = this.X;
                Worker.Push(ref wr, tail);
                Cont.Do(bK, ref wr, true);
                return;
            }
Beispiel #2
0
            internal override void DoJob(ref Worker wr, Cont <T> tK)
            {
                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.Full;
                Cont.Do(tK, ref wr, t);
                return;

EmptyOrDemand:
                WaitQueue.AddTaker(ref tM.Takers, new MVarReadCont <T>(tM, tK));
                tM.State = MVar.Demand;
            }
Beispiel #3
0
            internal override void DoJob(ref Worker wr, Cont <X> xK)
            {
                var work = wr.WorkStack;

                wr.WorkStack = null;
                Scheduler.PushAll(wr.Scheduler, work);
                Cont.Do(xK, ref wr, Do());
            }
Beispiel #4
0
                internal override void DoWork(ref Worker wr)
                {
                    var value = this.tF.Invoke(null);
                    var tK    = this.tK;

                    wr.Handler = tK;
                    Lock.Exit(this.l, ref wr);
                    Cont.Do(tK, ref wr, value);
                }
Beispiel #5
0
            internal override void TryAlt(ref Worker wr, int i, Cont <T> tK, 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.Full;
                Cont.Do(tK, ref wr, t);
                return;

AlreadyPicked:
                tM.State = MVar.Full;
                return;

EmptyOrDemand:
                WaitQueue.AddTaker(ref tM.Takers, i, pkSelf, new MVarReadCont <T>(tM, tK));
                tM.State = MVar.Demand;
                tE.TryElse(ref wr, i + 1);
                return;
            }
Beispiel #6
0
            internal override void DoJob(ref Worker wr, Cont <T> tK)
            {
                var l = this.l;

Spin:
                var state = l.State;

                if (state == Lock.Locked)
                {
                    goto Spin;
                }
                if (state != Interlocked.CompareExchange(ref l.State, Lock.Locked, state))
                {
                    goto Spin;
                }

                if (state == Lock.Free)
                {
                    goto GotIt;
                }

                var waiter = new GotIt(this.l, this.tF, tK);
                var tail   = l.Waiters;

                if (tail == null)
                {
                    waiter.Next = waiter;
                }
                else
                {
                    waiter.Next = tail.Next;
                    tail.Next   = waiter;
                }
                l.Waiters = waiter;
                l.State   = Lock.Held;
                return;

GotIt:
                // We keep the lock in Locked stated for the duration of the function
                // call.  This avoids doing a second interlocked operation.
                T value;

                try {
                    value = this.tF.Invoke(null);
                } catch (Exception e) {
                    tK    = new FailCont <T>(tK, e);
                    value = default(T);
                }
                l.State = Lock.Free;
                Cont.Do(tK, ref wr, value);
            }
Beispiel #7
0
 ///
 internal override void DoJob(ref Worker wr, Cont <ulong> rK)
 {
     Cont.Do(rK, ref wr, Randomizer.Next(ref wr.RandomLo, ref wr.RandomHi));
 }
Beispiel #8
0
 internal override void DoJob(ref Worker wr, Cont <X> xK)
 {
     Cont.Do(xK, ref wr, Do(Randomizer.Next(ref wr.RandomLo, ref wr.RandomHi)));
 }
Beispiel #9
0
 internal override void DoJob(ref Worker wr, Cont <X> xK)
 {
     Cont.Do(xK, ref wr, Do(xK.GetProc(ref wr)));
 }
Beispiel #10
0
            internal override void DoJob(ref Worker wr, Cont <FSharpOption <T> > xK)
            {
                xK.Value = null;
                var ch = this.ch;

TryNextGiver:
                ch.Lock.Enter();
                var tail = ch.Givers;

                if (null != tail)
                {
                    goto TryGiver;
                }
                ch.Lock.Exit();
                Work.Do(xK, ref wr);
                return;

TryGiver:
                var cursor = tail.Next;

                if (tail == cursor)
                {
                    ch.Givers = null;
                }
                else
                {
                    tail.Next = cursor.Next;
                }
                ch.Lock.Exit();

                var giver = cursor as Giver <T>;

                if (null == giver)
                {
                    goto GotSend;
                }

                var pkOther = giver.Pick;

                if (null == pkOther)
                {
                    goto GotGiver;
                }

TryPickOther:
                var stOther = Pick.TryPick(pkOther);

                if (stOther > 0)
                {
                    goto TryNextGiver;
                }
                if (stOther < 0)
                {
                    goto TryPickOther;
                }

                Pick.SetNacks(ref wr, giver.Me, pkOther);
GotGiver:
                Worker.Push(ref wr, giver.Cont);
GotSend:
                Cont.Do(xK, ref wr, FSharpOption <T> .Some(cursor.Value));
                return;
            }
Beispiel #11
0
 internal override void DoCont(ref Worker wr, T t)
 {
     tM.Fill(ref wr, t);
     Cont.Do(tK, ref wr, t);
 }