예제 #1
0
        public void StartThread(KThread Thread)
        {
            lock (SchedLock)
            {
                SchedulerThread SchedThread = new SchedulerThread(Thread);

                if (!AllThreads.TryAdd(Thread, SchedThread))
                {
                    return;
                }

                if (ActiveProcessors.Add(Thread.ProcessorId))
                {
                    Thread.Thread.Execute();

                    PrintDbgThreadInfo(Thread, "running.");
                }
                else
                {
                    WaitingToRun[Thread.ProcessorId].Push(SchedThread);

                    PrintDbgThreadInfo(Thread, "waiting to run.");
                }
            }
        }
예제 #2
0
 public bool HasThread(SchedulerThread SchedThread)
 {
     lock (Threads)
     {
         return(Threads.Contains(SchedThread));
     }
 }
예제 #3
0
        private void TryResumingExecution(SchedulerThread SchedThread)
        {
            KThread Thread = SchedThread.Thread;

            PrintDbgThreadInfo(Thread, "trying to resume...");

            SchedThread.WaitActivity.WaitOne();

            lock (SchedLock)
            {
                if (ActiveProcessors.Add(Thread.ProcessorId))
                {
                    PrintDbgThreadInfo(Thread, "resuming execution...");

                    return;
                }

                WaitingToRun[Thread.ProcessorId].Push(SchedThread);

                PrintDbgThreadInfo(Thread, "entering wait state...");
            }

            SchedThread.WaitSched.WaitOne();

            PrintDbgThreadInfo(Thread, "resuming execution...");
        }
예제 #4
0
        public void RemoveThread(KThread Thread)
        {
            PrintDbgThreadInfo(Thread, "exited.");

            lock (SchedLock)
            {
                if (AllThreads.TryRemove(Thread, out SchedulerThread SchedThread))
                {
                    WaitingToRun.Remove(SchedThread);

                    SchedThread.Dispose();
                }

                int ActualCore = Thread.ActualCore;

                SchedulerThread NewThread = WaitingToRun.Pop(ActualCore);

                if (NewThread == null)
                {
                    Log.PrintDebug(LogClass.KernelScheduler, $"Nothing to run on core {ActualCore}!");

                    CoreThreads[ActualCore] = null;

                    return;
                }

                NewThread.Thread.ActualCore = ActualCore;

                RunThread(NewThread);
            }
        }
예제 #5
0
 public bool Remove(SchedulerThread SchedThread)
 {
     lock (Threads)
     {
         return(Threads.Remove(SchedThread));
     }
 }
예제 #6
0
        public void Suspend(KThread Thread)
        {
            lock (SchedLock)
            {
                PrintDbgThreadInfo(Thread, "suspended.");

                int ActualCore = Thread.ActualCore;

                CoreReschedule[ActualCore] = false;

                SchedulerThread SchedThread = WaitingToRun.Pop(ActualCore);

                if (SchedThread != null)
                {
                    SchedThread.Thread.ActualCore = ActualCore;

                    CoreThreads[ActualCore] = SchedThread.Thread;

                    RunThread(SchedThread);
                }
                else
                {
                    Log.PrintDebug(LogClass.KernelScheduler, $"Nothing to run on core {Thread.ActualCore}!");

                    CoreThreads[ActualCore] = null;
                }
            }
        }
예제 #7
0
        public void StartThread(KThread Thread)
        {
            lock (SchedLock)
            {
                SchedulerThread SchedThread = new SchedulerThread(Thread);

                if (!AllThreads.TryAdd(Thread, SchedThread))
                {
                    return;
                }

                if (!ActiveProcessors.Contains(Thread.ProcessorId))
                {
                    ActiveProcessors.Add(Thread.ProcessorId);

                    Thread.Thread.Execute();

                    Logging.Debug($"{GetDbgThreadInfo(Thread)} running.");
                }
                else
                {
                    WaitingToRun[Thread.ProcessorId].Push(SchedThread);

                    Logging.Debug($"{GetDbgThreadInfo(SchedThread.Thread)} waiting to run.");
                }
            }
        }
예제 #8
0
        private void TryResumingExecution(SchedulerThread SchedThread)
        {
            KThread Thread = SchedThread.Thread;

            if (SchedThread.Active)
            {
                lock (SchedLock)
                {
                    if (ActiveProcessors.Add(Thread.ProcessorId))
                    {
                        PrintDbgThreadInfo(Thread, "resuming execution...");

                        return;
                    }

                    WaitingToRun[Thread.ProcessorId].Push(SchedThread);

                    PrintDbgThreadInfo(Thread, "entering wait state...");
                }
            }
            else
            {
                PrintDbgThreadInfo(Thread, "entering inactive wait state...");
            }

            SchedThread.WaitEvent.WaitOne();

            PrintDbgThreadInfo(Thread, "resuming execution...");
        }
예제 #9
0
 public void Push(SchedulerThread Thread)
 {
     lock (Threads)
     {
         Threads.Add(Thread);
     }
 }
예제 #10
0
        public void Yield(KThread Thread)
        {
            PrintDbgThreadInfo(Thread, "yielded execution.");

            if (IsActive(Thread))
            {
                lock (SchedLock)
                {
                    SchedulerThread SchedThread = WaitingToRun[Thread.ProcessorId].Pop(Thread.ActualPriority);

                    if (SchedThread == null)
                    {
                        PrintDbgThreadInfo(Thread, "resumed because theres nothing better to run.");

                        return;
                    }

                    if (SchedThread != null)
                    {
                        RunThread(SchedThread);
                    }
                }
            }
            else
            {
                //Just stop running the thread if it's not active,
                //and run whatever is waiting to run with the higuest priority.
                Suspend(Thread.ProcessorId);
            }

            Resume(Thread);
        }
예제 #11
0
        public void RemoveThread(KThread Thread)
        {
            PrintDbgThreadInfo(Thread, "exited.");

            lock (SchedLock)
            {
                if (AllThreads.TryRemove(Thread, out SchedulerThread SchedThread))
                {
                    WaitingToRun[Thread.ProcessorId].Remove(SchedThread);

                    SchedThread.Dispose();
                }

                SchedulerThread NewThread = WaitingToRun[Thread.ProcessorId].Pop();

                if (NewThread == null)
                {
                    Log.PrintDebug(LogClass.KernelScheduler, $"Nothing to run on core {Thread.ProcessorId}!");

                    ActiveProcessors.Remove(Thread.ProcessorId);

                    return;
                }

                RunThread(NewThread);
            }
        }
예제 #12
0
        public void EnterWait(KThread Thread, int TimeoutMs = Timeout.Infinite)
        {
            SchedulerThread SchedThread = AllThreads[Thread];

            Suspend(Thread);

            SchedThread.WaitSync.WaitOne(TimeoutMs);

            TryResumingExecution(SchedThread);
        }
예제 #13
0
 private void UpdateSyncWaitEvent(SchedulerThread SchedThread)
 {
     if (SchedThread.Active && SchedThread.SyncTimeout == 0)
     {
         SchedThread.SyncWaitEvent.Set();
     }
     else
     {
         SchedThread.SyncWaitEvent.Reset();
     }
 }
예제 #14
0
 private void RunThread(SchedulerThread SchedThread)
 {
     if (!SchedThread.Thread.Thread.Execute())
     {
         SchedThread.WaitEvent.Set();
     }
     else
     {
         Logging.Debug($"{GetDbgThreadInfo(SchedThread.Thread)} running.");
     }
 }
예제 #15
0
 private void RunThread(SchedulerThread SchedThread)
 {
     if (!SchedThread.Thread.Thread.Execute())
     {
         SchedThread.WaitSched.Set();
     }
     else
     {
         PrintDbgThreadInfo(SchedThread.Thread, "running.");
     }
 }
예제 #16
0
        private bool WaitIfNeeded(SchedulerThread SchedThread)
        {
            KThread Thread = SchedThread.Thread;

            if (!IsActive(SchedThread) && Thread.Thread.IsCurrentThread())
            {
                Suspend(Thread.ProcessorId);

                return(Resume(Thread));
            }
            else
            {
                return(false);
            }
        }
예제 #17
0
        public void Suspend(int ProcessorId)
        {
            lock (SchedLock)
            {
                SchedulerThread SchedThread = WaitingToRun[ProcessorId].Pop();

                if (SchedThread != null)
                {
                    RunThread(SchedThread);
                }
                else
                {
                    ActiveProcessors.Remove(ProcessorId);
                }
            }
        }
예제 #18
0
        public void Suspend(int ProcessorId)
        {
            lock (SchedLock)
            {
                SchedulerThread SchedThread = WaitingToRun[ProcessorId].Pop();

                if (SchedThread != null)
                {
                    RunThread(SchedThread);
                }
                else
                {
                    Log.PrintDebug(LogClass.KernelScheduler, $"Nothing to run on core {ProcessorId}!");

                    ActiveProcessors.Remove(ProcessorId);
                }
            }
        }
예제 #19
0
        public void Yield(KThread Thread)
        {
            PrintDbgThreadInfo(Thread, "yielded execution.");

            lock (SchedLock)
            {
                SchedulerThread SchedThread = WaitingToRun[Thread.ProcessorId].Pop(Thread.Priority);

                if (SchedThread == null)
                {
                    PrintDbgThreadInfo(Thread, "resumed because theres nothing better to run.");

                    return;
                }

                RunThread(SchedThread);
            }

            Resume(Thread);
        }
예제 #20
0
        private void TryResumingExecution(SchedulerThread SchedThread)
        {
            KThread Thread = SchedThread.Thread;

            lock (SchedLock)
            {
                if (ActiveProcessors.Add(Thread.ProcessorId))
                {
                    Logging.Debug($"{GetDbgThreadInfo(Thread)} resuming execution...");

                    return;
                }

                WaitingToRun[Thread.ProcessorId].Push(SchedThread);
            }

            SchedThread.WaitEvent.WaitOne();

            Logging.Debug($"{GetDbgThreadInfo(Thread)} resuming execution...");
        }
예제 #21
0
        public void Reschedule(KThread Thread)
        {
            bool NeedsReschedule;

            lock (SchedLock)
            {
                int ActualCore = Thread.ActualCore;

                NeedsReschedule = CoreReschedule[ActualCore];

                CoreReschedule[ActualCore] = false;
            }

            if (NeedsReschedule)
            {
                PrintDbgThreadInfo(Thread, "yielded execution.");

                lock (SchedLock)
                {
                    int ActualCore = Thread.ActualCore;

                    SchedulerThread NewThread = WaitingToRun.Pop(ActualCore, Thread.ActualPriority);

                    if (NewThread == null)
                    {
                        PrintDbgThreadInfo(Thread, "resumed because theres nothing better to run.");

                        return;
                    }

                    NewThread.Thread.ActualCore = ActualCore;

                    CoreThreads[ActualCore] = NewThread.Thread;

                    RunThread(NewThread);
                }

                Resume(Thread);
            }
        }
예제 #22
0
        private bool TryResumingExecution(SchedulerThread SchedThread)
        {
            KThread Thread = SchedThread.Thread;

            if (!SchedThread.Active || SchedThread.SyncTimeout != 0)
            {
                PrintDbgThreadInfo(Thread, "entering inactive wait state...");
            }

            bool Result = false;

            if (SchedThread.SyncTimeout != 0)
            {
                Result = SchedThread.SyncWaitEvent.WaitOne(SchedThread.SyncTimeout);

                SchedThread.SyncTimeout = 0;
            }

            lock (SchedLock)
            {
                if (ActiveProcessors.Add(Thread.ProcessorId))
                {
                    PrintDbgThreadInfo(Thread, "resuming execution...");

                    return(Result);
                }

                WaitingToRun[Thread.ProcessorId].Push(SchedThread);

                PrintDbgThreadInfo(Thread, "entering wait state...");
            }

            SchedThread.SchedWaitEvent.WaitOne();

            PrintDbgThreadInfo(Thread, "resuming execution...");

            return(Result);
        }
예제 #23
0
 private bool IsActive(SchedulerThread SchedThread)
 {
     return(SchedThread.Active && SchedThread.SyncTimeout == 0);
 }