Exemplo n.º 1
0
        internal static void Run(Scheduler sr, int me)
        {
            IsWorkerThread = true;

            var wr = new Worker();

            wr.Init(sr, 16000);
            wr.RandomHi = (ulong)DateTime.UtcNow.Ticks;

            var iK = new IdleCont();

            var wdm = (1L << 32) / sr.Events.Length;

            wr.Event = sr.Events[me];

            while (null != sr)
            {
                try {
Restart:
                    Work work = wr.WorkStack;
                    if (null == work)
                    {
                        goto EnterScheduler;
                    }

WorkerLoop:
                    wr.Handler = work;
                    {
                        var next = work.Next;
                        if (null != next && null == sr.WorkStack)
                        {
                            Scheduler.PushAll(sr, next);
                            next = null;
                        }
                        wr.WorkStack = next;
                    }
                    work.DoWork(ref wr);
                    work = wr.WorkStack;
                    if (null != work)
                    {
                        goto WorkerLoop;
                    }

                    wr.Handler = null;

EnterScheduler:
                    work = sr.WorkStack;
                    if (null == work)
                    {
                        goto TryIdle;
                    }

                    Scheduler.Enter(sr);
EnteredScheduler:
                    work = sr.WorkStack;
                    if (null == work)
                    {
                        goto ExitAndTryIdle;
                    }

                    SchedulerGotSome : {
                        var last         = work;
                        int numWorkStack = sr.NumWorkStack;
                        int n            = (int)((numWorkStack - 1L) * wdm >> 32) + 1;
                        sr.NumWorkStack = numWorkStack - n;
                        n -= 1;
                        while (n > 0)
                        {
                            last = last.Next;
                            n   -= 1;
                        }
                        var next = last.Next;
                        last.Next    = null;
                        sr.WorkStack = next;
                        if (null != next)
                        {
                            Scheduler.UnsafeSignal(sr);
                        }
                        Scheduler.Exit(sr);
                        goto WorkerLoop;
                    }

ExitAndTryIdle:
                    Scheduler.Exit(sr);

TryIdle:
                    iK.Value = Timeout.Infinite;

                    var iJ = sr.IdleHandler;
                    if (null != iJ)
                    {
                        wr.Handler = iK;
                        iJ.DoJob(ref wr, iK);
                    }

                    if (0 == iK.Value)
                    {
                        goto Restart;
                    }

                    Scheduler.Enter(sr);
                    work = sr.WorkStack;
                    if (null != work)
                    {
                        goto SchedulerGotSome;
                    }

                    Scheduler.UnsafeWait(sr, iK.Value, wr.Event);
                    goto EnteredScheduler;
                } catch (KillException) {
                    Scheduler.Kill(sr);
                    Scheduler.Dec(sr);
                    sr = null;
                } catch (Exception e) {
                    wr.WorkStack = new FailWork(wr.WorkStack, e, wr.Handler);
                }
            }
        }
Exemplo n.º 2
0
        internal static void Run(Scheduler sr, int me)
        {
            IsWorkerThread = true;

            var wr = new Worker();

            wr.Init(sr, 4000);

            var iK = new IdleCont();

            wr.Event = sr.Events[me];

            while (null != sr)
            {
                try {
Restart:
                    Work work = wr.WorkStack;
                    if (null == work)
                    {
                        goto EnterScheduler;
                    }

WorkerLoop:
                    wr.WorkStack = work.Next;
                    wr.Handler   = work;
                    work.DoWork(ref wr);
                    work = wr.WorkStack;
                    if (null != work)
                    {
                        goto WorkerLoop;
                    }

                    wr.Handler = null;

EnterScheduler:
                    work = sr.WorkStack;
                    if (null == work)
                    {
                        goto TryIdle;
                    }

                    Scheduler.Enter(sr);

                    work = sr.WorkStack;
                    if (null == work)
                    {
                        goto ExitAndTryIdle;
                    }

                    SchedulerGotSome : {
                        var last         = work;
                        int numWorkStack = sr.NumWorkStack - 1;
                        int n            = sr.NumWorkStack >> 2;
                        numWorkStack -= n;
                        while (n > 0)
                        {
                            last = last.Next;
                            n   -= 1;
                        }
                        var next = last.Next;
                        last.Next    = null;
                        sr.WorkStack = next;
                        if (null != next)
                        {
                            Scheduler.UnsafeSignal(sr);
                        }
                        sr.NumWorkStack = numWorkStack;
                        Scheduler.Exit(sr);
                        goto WorkerLoop;
                    }

ExitAndTryIdle:
                    Scheduler.Exit(sr);

TryIdle:
                    iK.Value = Timeout.Infinite;

                    var iJ = sr.IdleHandler;
                    if (null != iJ)
                    {
                        wr.Handler = iK;
                        iJ.DoJob(ref wr, iK);
                    }

                    if (0 == iK.Value)
                    {
                        goto Restart;
                    }

                    Scheduler.Enter(sr);
                    work = sr.WorkStack;
                    if (null != work)
                    {
                        goto SchedulerGotSome;
                    }

                    Scheduler.UnsafeWait(sr, iK.Value, wr.Event);
                    goto EnterScheduler;
                } catch (KillException) {
                    Scheduler.Kill(sr);
                    Scheduler.Dec(sr);
                    sr = null;
                } catch (Exception e) {
                    wr.WorkStack = new FailWork(wr.WorkStack, e, wr.Handler);
                }
            }
        }