예제 #1
0
        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;
        }
예제 #2
0
        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();
        }