public void YieldWithForcedLoadBalancing() { if (YieldCount == Owner.YieldCounter) { return; } System.CriticalSectionLock.Lock(); if (SchedFlags != ThreadSchedState.Running) { System.CriticalSectionLock.Unlock(); System.Scheduler.ContextSwitch(); return; } int Core = CurrentCore; CurrentCore = -1; if (Core >= 0) { SchedulingData.Unschedule(DynamicPriority, Core, this); SchedulingData.Suggest(DynamicPriority, Core, this); } if (Owner != null) { Owner.YieldCounter++; } KThread FirstScheduled = SchedulingData.ScheduledThreads(Core).FirstOrDefault(); KThread FirstSuggested = SchedulingData.SuggestedThreads(Core).FirstOrDefault(); if (FirstScheduled != null || FirstSuggested == null) { Scheduler.ThreadReselectionRequested = true; } else { foreach (KThread Thread in SchedulingData.SuggestedThreads(Core)) { if (Thread.CurrentCore >= 0) { KThread FirstCandidate = SchedulingData.SuggestedThreads(Thread.CurrentCore).FirstOrDefault(); if (FirstCandidate != Thread) { if (FirstCandidate == null || FirstCandidate.DynamicPriority >= 2) { SchedulingData.MoveTo(Thread.DynamicPriority, Core, Thread); if (Thread.Owner != null) { Thread.Owner.YieldCounter++; } if (Thread != this) { Scheduler.ThreadReselectionRequested = true; } else { YieldCount = Owner.YieldCounter; } } break; } } } } System.CriticalSectionLock.Unlock(); System.Scheduler.ContextSwitch(); }
public void YieldWithLoadBalancing() { int Prio = DynamicPriority; int Core = CurrentCore; System.CriticalSectionLock.Lock(); if (SchedFlags != ThreadSchedState.Running) { System.CriticalSectionLock.Unlock(); System.Scheduler.ContextSwitch(); return; } KThread NextThreadOnCurrentQueue = null; if (DynamicPriority < KScheduler.PrioritiesCount) { //Move current thread to the end of the queue. SchedulingData.Reschedule(Prio, Core, this); Func <KThread, bool> Predicate = x => x.DynamicPriority == Prio; NextThreadOnCurrentQueue = SchedulingData.ScheduledThreads(Core).FirstOrDefault(Predicate); } IEnumerable <KThread> SuitableCandidates() { foreach (KThread Thread in SchedulingData.SuggestedThreads(Core)) { int SrcCore = Thread.CurrentCore; if (SrcCore >= 0) { KThread SelectedSrcCore = Scheduler.CoreContexts[SrcCore].SelectedThread; if (SelectedSrcCore == Thread || ((SelectedSrcCore?.DynamicPriority ?? 2) < 2)) { continue; } } //If the candidate was scheduled after the current thread, then it's not worth it, //unless the priority is higher than the current one. if (NextThreadOnCurrentQueue.LastScheduledTicks >= Thread.LastScheduledTicks || NextThreadOnCurrentQueue.DynamicPriority < Thread.DynamicPriority) { yield return(Thread); } } } KThread Dst = SuitableCandidates().FirstOrDefault(x => x.DynamicPriority <= Prio); if (Dst != null) { SchedulingData.TransferToCore(Dst.DynamicPriority, Core, Dst); Scheduler.ThreadReselectionRequested = true; } if (this != NextThreadOnCurrentQueue) { Scheduler.ThreadReselectionRequested = true; } System.CriticalSectionLock.Unlock(); System.Scheduler.ContextSwitch(); }
public void YieldWithLoadBalancing() { System.CriticalSection.Enter(); if (SchedFlags != ThreadSchedState.Running) { System.CriticalSection.Leave(); System.Scheduler.ContextSwitch(); return; } int prio = DynamicPriority; int core = CurrentCore; KThread nextThreadOnCurrentQueue = null; if (DynamicPriority < KScheduler.PrioritiesCount) { //Move current thread to the end of the queue. _schedulingData.Reschedule(prio, core, this); Func <KThread, bool> predicate = x => x.DynamicPriority == prio; nextThreadOnCurrentQueue = _schedulingData.ScheduledThreads(core).FirstOrDefault(predicate); } IEnumerable <KThread> SuitableCandidates() { foreach (KThread thread in _schedulingData.SuggestedThreads(core)) { int srcCore = thread.CurrentCore; if (srcCore >= 0) { KThread selectedSrcCore = _scheduler.CoreContexts[srcCore].SelectedThread; if (selectedSrcCore == thread || ((selectedSrcCore?.DynamicPriority ?? 2) < 2)) { continue; } } //If the candidate was scheduled after the current thread, then it's not worth it, //unless the priority is higher than the current one. if (nextThreadOnCurrentQueue.LastScheduledTime >= thread.LastScheduledTime || nextThreadOnCurrentQueue.DynamicPriority < thread.DynamicPriority) { yield return(thread); } } } KThread dst = SuitableCandidates().FirstOrDefault(x => x.DynamicPriority <= prio); if (dst != null) { _schedulingData.TransferToCore(dst.DynamicPriority, core, dst); _scheduler.ThreadReselectionRequested = true; } if (this != nextThreadOnCurrentQueue) { _scheduler.ThreadReselectionRequested = true; } System.CriticalSection.Leave(); System.Scheduler.ContextSwitch(); }