internal static void Inc(Scheduler sr) { Enter(sr); Debug.Assert(0 <= sr.NumActive); sr.NumActive += 1; Exit(sr); }
internal static void Signal(Scheduler sr) { if (0 <= sr.WaiterStack) { Enter(sr); UnsafeSignal(sr); Exit(sr); } }
internal static void Push(Scheduler sr, Work work, Work last, int n) { Enter(sr); last.Next = sr.WorkStack; sr.WorkStack = work; sr.NumWorkStack += n; UnsafeSignal(sr); Exit(sr); }
internal static void UnsafeDec(Scheduler sr) { var numActive = sr.NumActive - 1; sr.NumActive = numActive; Debug.Assert(0 <= sr.NumActive); if (0 == numActive && 0 != sr.NumPulseWaiters) { Monitor.Enter(sr); Monitor.PulseAll(sr); Monitor.Exit(sr); } }
internal static void UnsafeSignal(Scheduler sr) { var waiter = sr.WaiterStack; if (0 <= waiter) { var ev = sr.Events[waiter]; sr.WaiterStack = ev.Next; Debug.Assert(0 <= sr.NumActive); sr.NumActive += 1; ev.Set(); } }
internal static void UnsafeWait(Scheduler sr, int ms, WorkerEvent ev) { ev.Next = sr.WaiterStack; sr.WaiterStack = ev.Me; UnsafeDec(sr); Exit(sr); ev.Wait(ms); Enter(sr); if (ev.IsSet) { ev.Reset(); } else { Debug.Assert(0 <= sr.NumActive); sr.NumActive += 1; int i = sr.WaiterStack; int me = ev.Me; if (i == me) { sr.WaiterStack = ev.Next; } else { WorkerEvent p = sr.Events[i]; while (p.Next != me) { p = sr.Events[p.Next]; } p.Next = ev.Next; } } }
internal static void Dec(Scheduler sr) { Enter(sr); UnsafeDec(sr); Exit(sr); }
internal static void Exit(Scheduler sr) { sr.Lock.Exit(); }
internal static void Enter(Scheduler sr) { sr.Lock.Enter(); }
/// <summary>Kills the worker threads of the scheduler one-by-one. This /// should only be used with a local scheduler that is known to be /// idle.</summary> public static void Kill(Scheduler sr) { var work = new AbortWork(); PushAll(sr, work); }
internal static void PushAllAndDec(Scheduler sr, Work work) { if (null == work) { Dec(sr); } else { var n = 1; var last = work; FindLast: var next = last.Next; if (null == next) goto FoundLast; n += 1; last = next; goto FindLast; FoundLast: PushAndDec(sr, work, last, n); } }
internal static void PushAndDec(Scheduler sr, Work work, Work last, int n) { Enter(sr); last.Next = sr.WorkStack; sr.WorkStack = work; sr.NumWorkStack += n; sr.NumActive -= 1; Debug.Assert(0 <= sr.NumActive); UnsafeSignal(sr); Exit(sr); }
internal static void PushAll(Scheduler sr, Work work) { if (null == work) return; var n = 1; var last = work; FindLast: var next = last.Next; if (null == next) goto FoundLast; n += 1; last = next; goto FindLast; FoundLast: Push(sr, work, last, n); }
internal static void PushNew(Scheduler sr, Work work) { Push(sr, work, work, 1); }