Ejemplo n.º 1
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();
        }
Ejemplo n.º 2
0
        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();
        }
Ejemplo n.º 3
0
        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();
        }