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); } } }
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); } } }