private void AdjustScheduling(ThreadSchedState OldFlags) { if (OldFlags == SchedFlags) { return; } if (OldFlags == ThreadSchedState.Running) { //Was running, now it's stopped. if (CurrentCore >= 0) { SchedulingData.Unschedule(DynamicPriority, CurrentCore, this); } for (int Core = 0; Core < KScheduler.CpuCoresCount; Core++) { if (Core != CurrentCore && ((AffinityMask >> Core) & 1) != 0) { SchedulingData.Unsuggest(DynamicPriority, Core, this); } } } else if (SchedFlags == ThreadSchedState.Running) { //Was stopped, now it's running. if (CurrentCore >= 0) { SchedulingData.Schedule(DynamicPriority, CurrentCore, this); } for (int Core = 0; Core < KScheduler.CpuCoresCount; Core++) { if (Core != CurrentCore && ((AffinityMask >> Core) & 1) != 0) { SchedulingData.Suggest(DynamicPriority, Core, this); } } } Scheduler.ThreadReselectionRequested = true; }
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(); }