int RunSchedulerLoop(List <Timer> new_time) { int ms_wait = -1; int i; int count = list.Count; long ticks = GetTimeMonotonic(); for (i = 0; i < count; i++) { Timer timer = (Timer)list.GetByIndex(i); if (timer.next_run > ticks) { break; } list.RemoveAt(i); count--; i--; ThreadPool.UnsafeQueueUserWorkItem(TimerCB, timer); long period = timer.period_ms; long due_time = timer.due_time_ms; bool no_more = (period == -1 || ((period == 0 || period == Timeout.Infinite) && due_time != Timeout.Infinite)); if (no_more) { timer.next_run = Int64.MaxValue; } else { timer.next_run = GetTimeMonotonic() + TimeSpan.TicksPerMillisecond * timer.period_ms; new_time.Add(timer); } } // Reschedule timers with a new due time count = new_time.Count; for (i = 0; i < count; i++) { Timer timer = new_time [i]; Add(timer); } new_time.Clear(); ShrinkIfNeeded(new_time, 512); // Shrink the list int capacity = list.Capacity; count = list.Count; if (capacity > 1024 && count > 0 && (capacity / count) > 3) { list.Capacity = count * 2; } long min_next_run = Int64.MaxValue; if (list.Count > 0) { min_next_run = ((Timer)list.GetByIndex(0)).next_run; } //PrintList (); ms_wait = -1; if (min_next_run != Int64.MaxValue) { long diff = (min_next_run - GetTimeMonotonic()) / TimeSpan.TicksPerMillisecond; if (diff > Int32.MaxValue) { ms_wait = Int32.MaxValue - 1; } else { ms_wait = (int)(diff); if (ms_wait < 0) { ms_wait = 0; } } } return(ms_wait); }
void SchedulerThread() { Thread.CurrentThread.Name = "Timer-Scheduler"; var new_time = new List <Timer> (512); while (true) { int ms_wait = -1; long ticks = GetTimeMonotonic(); lock (this) { changed.Reset(); //PrintList (); int i; int count = list.Count; for (i = 0; i < count; i++) { Timer timer = (Timer)list.GetByIndex(i); if (timer.next_run > ticks) { break; } list.RemoveAt(i); count--; i--; ThreadPool.UnsafeQueueUserWorkItem(TimerCB, timer); long period = timer.period_ms; long due_time = timer.due_time_ms; bool no_more = (period == -1 || ((period == 0 || period == Timeout.Infinite) && due_time != Timeout.Infinite)); if (no_more) { timer.next_run = Int64.MaxValue; } else { timer.next_run = GetTimeMonotonic() + TimeSpan.TicksPerMillisecond * timer.period_ms; new_time.Add(timer); } } // Reschedule timers with a new due time count = new_time.Count; for (i = 0; i < count; i++) { Timer timer = new_time [i]; Add(timer); } new_time.Clear(); ShrinkIfNeeded(new_time, 512); // Shrink the list int capacity = list.Capacity; count = list.Count; if (capacity > 1024 && count > 0 && (capacity / count) > 3) { list.Capacity = count * 2; } long min_next_run = Int64.MaxValue; if (list.Count > 0) { min_next_run = ((Timer)list.GetByIndex(0)).next_run; } //PrintList (); ms_wait = -1; if (min_next_run != Int64.MaxValue) { long diff = (min_next_run - GetTimeMonotonic()) / TimeSpan.TicksPerMillisecond; if (diff > Int32.MaxValue) { ms_wait = Int32.MaxValue - 1; } else { ms_wait = (int)(diff); if (ms_wait < 0) { ms_wait = 0; } } } } // Wait until due time or a timer is changed and moves from/to the first place in the list. changed.WaitOne(ms_wait); } }
public void UnsafeOnCompleted(Action continuation) { Debug.Assert(_continuation is null); _continuation = continuation; ThreadPool.UnsafeQueueUserWorkItem(this, preferLocal: true); }