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); } }
private void TryResumingExecution(SchedulerThread SchedThread) { KThread Thread = SchedThread.Thread; PrintDbgThreadInfo(Thread, "trying to resume..."); SchedThread.WaitActivity.WaitOne(); lock (SchedLock) { if (TryAddToCore(Thread)) { PrintDbgThreadInfo(Thread, "resuming execution..."); return; } WaitingToRun.Push(SchedThread); SetReschedule(Thread.ProcessorId); PrintDbgThreadInfo(Thread, "entering wait state..."); } SchedThread.WaitSched.WaitOne(); PrintDbgThreadInfo(Thread, "resuming execution..."); }
public void StartThread(KThread Thread) { lock (SchedLock) { SchedulerThread SchedThread = new SchedulerThread(Thread); if (!AllThreads.TryAdd(Thread, SchedThread)) { return; } if (TryAddToCore(Thread)) { Thread.Thread.Execute(); PrintDbgThreadInfo(Thread, "running."); } else { WaitingToRun.Push(SchedThread); PrintDbgThreadInfo(Thread, "waiting to run."); } } }
private void Yield(KThread Thread, int MinPriority) { PrintDbgThreadInfo(Thread, "yielded execution."); lock (SchedLock) { int ActualCore = Thread.ActualCore; SchedulerThread NewThread = WaitingToRun.Pop(ActualCore, MinPriority); if (NewThread != null) { NewThread.Thread.ActualCore = ActualCore; CoreThreads[ActualCore] = NewThread.Thread; RunThread(NewThread); } else { CoreThreads[ActualCore] = null; } } Resume(Thread); }
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; } } }
public void ChangeCore(KThread Thread, int IdealCore, int CoreMask) { lock (SchedLock) { if (IdealCore != -3) { Thread.IdealCore = IdealCore; } Thread.CoreMask = CoreMask; if (AllThreads.ContainsKey(Thread)) { SetReschedule(Thread.ActualCore); SchedulerThread SchedThread = AllThreads[Thread]; //Note: Aways if the thread is on the queue first, and try //adding to a new core later, to ensure that a thread that //is already running won't be added to another core. if (WaitingToRun.HasThread(SchedThread) && TryAddToCore(Thread)) { WaitingToRun.Remove(SchedThread); RunThread(SchedThread); } } } }
public void EnterWait(KThread Thread, int TimeoutMs = Timeout.Infinite) { SchedulerThread SchedThread = AllThreads[Thread]; Suspend(Thread); SchedThread.WaitSync.WaitOne(TimeoutMs); TryResumingExecution(SchedThread); }
private void RunThread(SchedulerThread SchedThread) { if (!SchedThread.Thread.Thread.Execute()) { PrintDbgThreadInfo(SchedThread.Thread, "waked."); SchedThread.WaitSched.Set(); } else { PrintDbgThreadInfo(SchedThread.Thread, "running."); } }
public void SetThreadActivity(KThread Thread, bool Active) { SchedulerThread SchedThread = AllThreads[Thread]; SchedThread.IsActive = Active; if (Active) { SchedThread.WaitActivity.Set(); } else { SchedThread.WaitActivity.Reset(); } }