Beispiel #1
0
            internal override void DoJob(ref Worker wr, Cont <Unit> uK)
            {
                var tI = this.tI;

                tI.Value = this.t; // This assumes correct usage of IVar.
Spin:
                var state = tI.State;

                if (state < Delayed)
                {
                    goto Spin;
                }
                if (state != Interlocked.CompareExchange(ref tI.State, HasValue, state))
                {
                    goto Spin;
                }

                if (state > Running)
                {
                    uK.DoHandle(ref wr, new Exception("IVar full"));
                }
                else
                {
                    WaitQueue.PickReaders(ref tI.Readers, tI.Value, ref wr);
                    Work.Do(uK, ref wr);
                }
            }
Beispiel #2
0
            internal override void DoJob(ref Worker wr, Cont <Unit> uK)
            {
                var tI = this.tI;

Spin:
                var state = tI.State;

                if (state < Delayed)
                {
                    goto Spin;
                }
                if (state != Interlocked.CompareExchange(ref tI.State, ~state, state))
                {
                    goto Spin;
                }

                if (state > Running)
                {
                    goto IVarFull;
                }

                tI.Value = this.t;
                tI.State = HasValue;

                WaitQueue.PickReaders(ref tI.Readers, tI.Value, ref wr);
                Work.Do(uK, ref wr);
                return;

IVarFull:
                tI.State = state;
                uK.DoHandle(ref wr, new Exception("IVar full"));
            }
Beispiel #3
0
            internal override void DoJob(ref Worker wr, Cont <Unit> uK)
            {
                var tI = this.tI;

Spin:
                var state = tI.State;

                if (state < Delayed)
                {
                    goto Spin;
                }
                if (state != Interlocked.CompareExchange(ref tI.State, ~state, state))
                {
                    goto Spin;
                }

                if (state > Running)
                {
                    goto IVarFull;
                }

                var readers = tI.Readers;
                var e       = this.e;

                tI.Readers = new Fail <T>(e);
                tI.State   = HasExn;

                WaitQueue.FailReaders(readers, e, ref wr);
                Work.Do(uK, ref wr);
                return;

IVarFull:
                uK.DoHandle(ref wr, new Exception("IVar full"));
            }
Beispiel #4
0
        internal override void DoJob(ref Worker wr, Cont <T> aK)
        {
Spin:
            var state = this.State;

Reconsider:
            if (state > Running)
            {
                goto Completed;
            }
            if (state < Delayed)
            {
                goto Spin;
            }
            var check = state;

            state = Interlocked.CompareExchange(ref this.State, state - MakeLocked, state);
            if (Delayed == state)
            {
                goto Delayed;
            }
            if (state != check)
            {
                goto Reconsider;
            }

            WaitQueue.AddTaker(ref this.Readers, aK);
            this.State = Running;
            return;

Delayed:
            var readers = this.Readers;

            this.Readers = null;
            this.State   = Running;

            var fulfill = readers as Fulfill;

            fulfill.tP     = this;
            fulfill.reader = aK;
            var tJ = fulfill.tJ;

            fulfill.tJ = null;
            Job.Do(tJ, ref wr, fulfill);
            return;

Completed:
            if (state == HasValue)
            {
                Cont.Do(aK, ref wr, this.Value);
            }
            else
            {
                aK.DoHandle(ref wr, (this.Readers as Fail <T>).exn);
            }
        }
Beispiel #5
0
        /// Internal implementation detail.
        internal override void DoJob(ref Worker wr, Cont <T> aK)
        {
Spin:
            var state = this.State;

            if (state < Running)
            {
                goto Completed;
            }
            if (state == Locked)
            {
                goto Spin;
            }
            if (state != Interlocked.CompareExchange(ref this.State, Locked, state))
            {
                goto Spin;
            }

            if (state == Running)
            {
                goto Running;
            }

            var job = this.Readers as Cont;

            var taker = new Taker <T>();

            taker.Cont   = aK;
            taker.Next   = taker;
            this.Readers = taker;

            this.State = Running;

            job.DoWork(ref wr);
            return;

Running:
            WaitQueue.AddTaker(ref this.Readers, aK);
            this.State = Running;
            return;

Completed:
            if (state == Completed)
            {
                aK.DoCont(ref wr, this.Value);
            }
            else
            {
                aK.DoHandle(ref wr, (this.Readers as Fail).exn);
            }
        }
Beispiel #6
0
        internal override void TryAlt(ref Worker wr, int i, Cont <T> aK, Else aE)
        {
Spin:
            var state = this.State;

Reconsider:
            if (state > Running)
            {
                goto Completed;
            }
            if (state < Delayed)
            {
                goto Spin;
            }
            var check = state;

            state = Interlocked.CompareExchange(ref this.State, state - MakeLocked, state);
            if (Delayed == state)
            {
                goto Delayed;
            }
            if (state != check)
            {
                goto Reconsider;
            }

            WaitQueue.AddTaker(ref this.Readers, i, aE.pk, aK);
            this.State = Running;
            aE.TryElse(ref wr, i + 1);
            return;

Delayed:
            var readers = this.Readers;

            this.Readers = null;
            this.State   = Running;

            var fulfill = readers as Fulfill;

            fulfill.reader = aK;
            fulfill.me     = i;
            fulfill.pk     = aE.pk;

            Worker.PushNew(ref wr, fulfill);
            aE.TryElse(ref wr, i + i);
            return;

Completed:
            var pkSelf = aE.pk;

TryPick:
            var stSelf = Pick.TryPick(pkSelf);

            if (stSelf > 0)
            {
                goto AlreadyPicked;
            }
            if (stSelf < 0)
            {
                goto TryPick;
            }

            Pick.SetNacks(ref wr, i, pkSelf);

            if (state == HasValue)
            {
                Cont.Do(aK, ref wr, this.Value);
            }
            else
            {
                aK.DoHandle(ref wr, (this.Readers as Fail <T>).exn);
            }
AlreadyPicked:
            return;
        }
Beispiel #7
0
        internal override void TryAlt(ref Worker wr, int i, Cont <T> aK, Else aE)
        {
            var pkSelf = aE.pk;

Spin:
            var state = this.State;

            if (state > Running)
            {
                goto Completed;
            }
            if (state < Delayed)
            {
                goto Spin;
            }
            if (state != Interlocked.CompareExchange(ref this.State, ~state, state))
            {
                goto Spin;
            }

            if (Delayed == state)
            {
                goto Delayed;
            }

            WaitQueue.AddTaker(ref this.Readers, i, pkSelf, aK);
            this.State = Running;
            aE.TryElse(ref wr, i + 1);
            return;

Delayed:
            var taker = new Taker <T>();

            taker.Cont = aK;
            taker.Me   = i;
            taker.Pick = pkSelf;
            taker.Next = taker;

            var readers = this.Readers;

            this.Readers = taker;
            this.State   = Running;

            var fulfill = readers as Fulfill;
            var tJ      = fulfill.tP;

            fulfill.tP = this;
            Worker.PushNew(ref wr, new JobWork <T>(tJ, fulfill));
            aE.TryElse(ref wr, i + i);
            return;

Completed:
            var stSelf = Pick.TryPick(pkSelf);

            if (stSelf > 0)
            {
                goto AlreadyPicked;
            }
            if (stSelf < 0)
            {
                goto Completed;
            }

            Pick.SetNacks(ref wr, i, pkSelf);

            if (state == HasValue)
            {
                Cont.Do(aK, ref wr, this.Value);
            }
            else
            {
                aK.DoHandle(ref wr, (this.Readers as Fail <T>).exn);
            }
AlreadyPicked:
            return;
        }
Beispiel #8
0
        /// Internal implementation detail.
        internal override void TryAlt(ref Worker wr, int i, Pick pkSelf, Cont <T> aK)
        {
Spin:
            var state = this.State;

            if (state < Running)
            {
                goto Completed;
            }
            if (state == Locked)
            {
                goto Spin;
            }
            if (state != Interlocked.CompareExchange(ref this.State, Locked, state))
            {
                goto Spin;
            }

            if (state == Running)
            {
                goto Running;
            }

            var job = this.Readers as Cont;

            var taker = new Taker <T>();

            taker.Me     = i;
            taker.Pick   = pkSelf;
            taker.Cont   = aK;
            taker.Next   = taker;
            this.Readers = taker;

            this.State = Running;

            Worker.Push(ref wr, job);
            aK.TryNext(ref wr, i + 1, pkSelf);
            return;

Running:
            WaitQueue.AddTaker(ref this.Readers, i, pkSelf, aK);
            this.State = Running;
            aK.TryNext(ref wr, i + 1, pkSelf);
            return;

Completed:
            var stSelf = Pick.TryPick(pkSelf);

            if (stSelf > 0)
            {
                goto AlreadyPicked;
            }
            if (stSelf < 0)
            {
                goto Completed;
            }

            Pick.SetNacks(ref wr, i, pkSelf);

            if (state == Completed)
            {
                aK.DoCont(ref wr, this.Value);
            }
            else
            {
                aK.DoHandle(ref wr, (this.Readers as Fail).exn);
            }
AlreadyPicked:
            return;
        }