private void PreemptThread(int prio, int core) { IEnumerable <KThread> scheduledThreads = SchedulingData.ScheduledThreads(core); KThread selectedThread = scheduledThreads.FirstOrDefault(x => x.DynamicPriority == prio); // Yield priority queue. if (selectedThread != null) { SchedulingData.Reschedule(prio, core, selectedThread); } IEnumerable <KThread> SuitableCandidates() { foreach (KThread thread in SchedulingData.SuggestedThreads(core)) { int srcCore = thread.CurrentCore; if (srcCore >= 0) { KThread highestPrioSrcCore = SchedulingData.ScheduledThreads(srcCore).FirstOrDefault(); if (highestPrioSrcCore != null && highestPrioSrcCore.DynamicPriority < 2) { break; } if (highestPrioSrcCore == thread) { continue; } } // If the candidate was scheduled after the current thread, then it's not worth it. if (selectedThread == null || selectedThread.LastScheduledTime >= thread.LastScheduledTime) { yield return(thread); } } } // Select candidate threads that could run on this core. // Only take into account threads that are not yet selected. KThread dst = SuitableCandidates().FirstOrDefault(x => x.DynamicPriority == prio); if (dst != null) { SchedulingData.TransferToCore(prio, core, dst); selectedThread = dst; } // If the priority of the currently selected thread is lower than preemption priority, // then allow threads with lower priorities to be selected aswell. if (selectedThread != null && selectedThread.DynamicPriority > prio) { Func <KThread, bool> predicate = x => x.DynamicPriority >= selectedThread.DynamicPriority; dst = SuitableCandidates().FirstOrDefault(predicate); if (dst != null) { SchedulingData.TransferToCore(dst.DynamicPriority, core, dst); } } ThreadReselectionRequested = true; }
private void PreemptThread(int Prio, int Core) { IEnumerable <KThread> ScheduledThreads = SchedulingData.ScheduledThreads(Core); KThread SelectedThread = ScheduledThreads.FirstOrDefault(x => x.DynamicPriority == Prio); //Yield priority queue. if (SelectedThread != null) { SchedulingData.Reschedule(Prio, Core, SelectedThread); } IEnumerable <KThread> SuitableCandidates() { foreach (KThread Thread in SchedulingData.SuggestedThreads(Core)) { int SrcCore = Thread.CurrentCore; if (SrcCore >= 0) { KThread HighestPrioSrcCore = SchedulingData.ScheduledThreads(SrcCore).FirstOrDefault(); if (HighestPrioSrcCore != null && HighestPrioSrcCore.DynamicPriority < 2) { break; } if (HighestPrioSrcCore == Thread) { continue; } } //If the candidate was scheduled after the current thread, then it's not worth it. if (SelectedThread == null || SelectedThread.LastScheduledTicks >= Thread.LastScheduledTicks) { yield return(Thread); } } } //Select candidate threads that could run on this core. //Only take into account threads that are not yet selected. KThread Dst = SuitableCandidates().FirstOrDefault(x => x.DynamicPriority == Prio); if (Dst != null) { SchedulingData.TransferToCore(Prio, Core, Dst); SelectedThread = Dst; } //If the priority of the currently selected thread is lower than preemption priority, //then allow threads with lower priorities to be selected aswell. if (SelectedThread != null && SelectedThread.DynamicPriority > Prio) { Func <KThread, bool> Predicate = x => x.DynamicPriority >= SelectedThread.DynamicPriority; Dst = SuitableCandidates().FirstOrDefault(Predicate); if (Dst != null) { SchedulingData.TransferToCore(Dst.DynamicPriority, Core, Dst); } } ThreadReselectionRequested = true; }