diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-05-14 03:01:10 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-05-14 03:01:10 -0300 |
| commit | ee0b14ba0811a76a306c1546be90de128a17f5cc (patch) | |
| tree | cab7c14081ccaa31090ab4e76759d14079f0fea2 /Ryujinx.Core/OsHle/Handles | |
| parent | 9e50ed53e67f4bdc58aed37d116b289c70abd312 (diff) | |
Some improvements to SetThreadCoreMask, simplified implementation of wait lists
Diffstat (limited to 'Ryujinx.Core/OsHle/Handles')
| -rw-r--r-- | Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs | 78 | ||||
| -rw-r--r-- | Ryujinx.Core/OsHle/Handles/KThread.cs | 148 |
2 files changed, 61 insertions, 165 deletions
diff --git a/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs b/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs index 33f7fb14..487a8147 100644 --- a/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs +++ b/Ryujinx.Core/OsHle/Handles/KProcessScheduler.cs @@ -66,17 +66,21 @@ namespace Ryujinx.Core.OsHle.Handles SchedThread.Dispose(); } - SchedulerThread NewThread = WaitingToRun.Pop(Thread.ActualCore); + int ActualCore = Thread.ActualCore; + + SchedulerThread NewThread = WaitingToRun.Pop(ActualCore); if (NewThread == null) { - Log.PrintDebug(LogClass.KernelScheduler, $"Nothing to run on core {Thread.ActualCore}!"); + Log.PrintDebug(LogClass.KernelScheduler, $"Nothing to run on core {ActualCore}!"); - RemoveActiveCore(Thread.ActualCore); + RemoveActiveCore(ActualCore); return; } + NewThread.Thread.ActualCore = ActualCore; + RunThread(NewThread); } } @@ -146,17 +150,21 @@ namespace Ryujinx.Core.OsHle.Handles { PrintDbgThreadInfo(Thread, "suspended."); - SchedulerThread SchedThread = WaitingToRun.Pop(Thread.ActualCore); + int ActualCore = Thread.ActualCore; + + SchedulerThread SchedThread = WaitingToRun.Pop(ActualCore); if (SchedThread != null) { + SchedThread.Thread.ActualCore = ActualCore; + RunThread(SchedThread); } else { Log.PrintDebug(LogClass.KernelScheduler, $"Nothing to run on core {Thread.ActualCore}!"); - RemoveActiveCore(Thread.ActualCore); + RemoveActiveCore(ActualCore); } } } @@ -169,9 +177,9 @@ namespace Ryujinx.Core.OsHle.Handles { lock (SchedLock) { - SchedulerThread SchedThread = WaitingToRun.Pop( - Thread.ActualCore, - Thread.ActualPriority); + int ActualCore = Thread.ActualCore; + + SchedulerThread SchedThread = WaitingToRun.Pop(ActualCore, Thread.ActualPriority); if (SchedThread == null) { @@ -182,6 +190,8 @@ namespace Ryujinx.Core.OsHle.Handles if (SchedThread != null) { + SchedThread.Thread.ActualCore = ActualCore; + RunThread(SchedThread); } } @@ -198,24 +208,24 @@ namespace Ryujinx.Core.OsHle.Handles public bool TryRunning(KThread Thread) { - if (!AllThreads.TryGetValue(Thread, out SchedulerThread SchedThread)) - { - throw new InvalidOperationException(); - } - - lock (SchedLock) + //Failing to get the thread here is fine, + //the thread may not have been started yet. + if (AllThreads.TryGetValue(Thread, out SchedulerThread SchedThread)) { - if (WaitingToRun.HasThread(SchedThread) && AddActiveCore(Thread)) + lock (SchedLock) { - WaitingToRun.Remove(SchedThread); + if (WaitingToRun.HasThread(SchedThread) && AddActiveCore(Thread)) + { + WaitingToRun.Remove(SchedThread); - RunThread(SchedThread); + RunThread(SchedThread); - return true; + return true; + } } - - return false; } + + return false; } public void Resume(KThread Thread) @@ -289,18 +299,25 @@ namespace Ryujinx.Core.OsHle.Handles private bool AddActiveCore(KThread Thread) { + int CoreMask; + lock (SchedLock) { //First, try running it on Ideal Core. - int CoreMask = 1 << Thread.IdealCore; + int IdealCore = Thread.IdealCore; - if ((ActiveCores & CoreMask) == 0) + if (IdealCore != -1) { - ActiveCores |= CoreMask; + CoreMask = 1 << IdealCore; - Thread.ActualCore = Thread.IdealCore; + if ((ActiveCores & CoreMask) == 0) + { + ActiveCores |= CoreMask; + + Thread.ActualCore = IdealCore; - return true; + return true; + } } //If that fails, then try running on any core allowed by Core Mask. @@ -340,11 +357,12 @@ namespace Ryujinx.Core.OsHle.Handles private void PrintDbgThreadInfo(KThread Thread, string Message) { Log.PrintDebug(LogClass.KernelScheduler, "(" + - "ThreadId = " + Thread.ThreadId + ", " + - "ActualCore = " + Thread.ActualCore + ", " + - "IdealCore = " + Thread.IdealCore + ", " + - "ActualPriority = " + Thread.ActualPriority + ", " + - "WantedPriority = " + Thread.WantedPriority + ") " + Message); + "ThreadId = " + Thread.ThreadId + ", " + + "CoreMask = 0x" + Thread.CoreMask.ToString("x1") + ", " + + "ActualCore = " + Thread.ActualCore + ", " + + "IdealCore = " + Thread.IdealCore + ", " + + "ActualPriority = " + Thread.ActualPriority + ", " + + "WantedPriority = " + Thread.WantedPriority + ") " + Message); } public void Dispose() diff --git a/Ryujinx.Core/OsHle/Handles/KThread.cs b/Ryujinx.Core/OsHle/Handles/KThread.cs index a430974c..ce9c3db2 100644 --- a/Ryujinx.Core/OsHle/Handles/KThread.cs +++ b/Ryujinx.Core/OsHle/Handles/KThread.cs @@ -1,5 +1,5 @@ using ChocolArm64; -using System; +using System.Collections.Generic; namespace Ryujinx.Core.OsHle.Handles { @@ -14,16 +14,15 @@ namespace Ryujinx.Core.OsHle.Handles private Process Process; - public KThread NextMutexThread { get; set; } - public KThread NextCondVarThread { get; set; } + public List<KThread> MutexWaiters { get; private set; } public KThread MutexOwner { get; set; } public int ActualPriority { get; private set; } public int WantedPriority { get; private set; } - public int IdealCore { get; set; } public int ActualCore { get; set; } + public int IdealCore { get; set; } public int WaitHandle { get; set; } @@ -39,6 +38,8 @@ namespace Ryujinx.Core.OsHle.Handles this.Process = Process; this.IdealCore = IdealCore; + MutexWaiters = new List<KThread>(); + CoreMask = 1 << IdealCore; ActualPriority = WantedPriority = Priority; @@ -57,147 +58,24 @@ namespace Ryujinx.Core.OsHle.Handles int CurrPriority = WantedPriority; - if (NextMutexThread != null && CurrPriority > NextMutexThread.WantedPriority) - { - CurrPriority = NextMutexThread.WantedPriority; - } - - if (CurrPriority != OldPriority) + lock (Process.ThreadSyncLock) { - ActualPriority = CurrPriority; - - UpdateWaitLists(); - - MutexOwner?.UpdatePriority(); - } - } - - private void UpdateWaitLists() - { - UpdateMutexList(); - UpdateCondVarList(); - - Process.Scheduler.Resort(this); - } - - private void UpdateMutexList() - { - KThread OwnerThread = MutexOwner; - - if (OwnerThread == null) - { - return; - } - - //The MutexOwner field should only be non-null when the thread is - //waiting for the lock, and the lock belongs to another thread. - if (OwnerThread == this) - { - throw new InvalidOperationException(); - } - - lock (OwnerThread) - { - //Remove itself from the list. - KThread CurrThread = OwnerThread; - - while (CurrThread.NextMutexThread != null) + foreach (KThread Thread in MutexWaiters) { - if (CurrThread.NextMutexThread == this) + if (CurrPriority > Thread.WantedPriority) { - CurrThread.NextMutexThread = NextMutexThread; - - break; + CurrPriority = Thread.WantedPriority; } - - CurrThread = CurrThread.NextMutexThread; - } - - //Re-add taking new priority into account. - CurrThread = OwnerThread; - - while (CurrThread.NextMutexThread != null) - { - if (CurrThread.NextMutexThread.ActualPriority > ActualPriority) - { - break; - } - - CurrThread = CurrThread.NextMutexThread; } - - NextMutexThread = CurrThread.NextMutexThread; - - CurrThread.NextMutexThread = this; } - } - private void UpdateCondVarList() - { - lock (Process.ThreadArbiterListLock) + if (CurrPriority != OldPriority) { - if (Process.ThreadArbiterListHead == null) - { - return; - } - - //Remove itself from the list. - bool Found; - - KThread CurrThread = Process.ThreadArbiterListHead; - - if (Found = (Process.ThreadArbiterListHead == this)) - { - Process.ThreadArbiterListHead = Process.ThreadArbiterListHead.NextCondVarThread; - } - else - { - while (CurrThread.NextCondVarThread != null) - { - if (CurrThread.NextCondVarThread == this) - { - CurrThread.NextCondVarThread = NextCondVarThread; - - Found = true; - - break; - } - - CurrThread = CurrThread.NextCondVarThread; - } - } - - if (!Found) - { - return; - } - - //Re-add taking new priority into account. - if (Process.ThreadArbiterListHead == null || - Process.ThreadArbiterListHead.ActualPriority > ActualPriority) - { - NextCondVarThread = Process.ThreadArbiterListHead; - - Process.ThreadArbiterListHead = this; - - return; - } - - CurrThread = Process.ThreadArbiterListHead; - - while (CurrThread.NextCondVarThread != null) - { - if (CurrThread.NextCondVarThread.ActualPriority > ActualPriority) - { - break; - } - - CurrThread = CurrThread.NextCondVarThread; - } + ActualPriority = CurrPriority; - NextCondVarThread = CurrThread.NextCondVarThread; + Process.Scheduler.Resort(this); - CurrThread.NextCondVarThread = this; + MutexOwner?.UpdatePriority(); } } } |
