diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-05-13 00:22:42 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-05-13 00:22:42 -0300 |
| commit | 4546d1b9be1052bbf82858d97795b33355bf64da (patch) | |
| tree | a88286d145d8da522a81b3a265c538e7795b7f8d /Ryujinx.Core/OsHle/Handles/KThread.cs | |
| parent | 3603497a137d14f2d65c5450133f2486a9f9620c (diff) | |
Initial work to support changing thread core on the scheduler, also some cond var priority fixes
Diffstat (limited to 'Ryujinx.Core/OsHle/Handles/KThread.cs')
| -rw-r--r-- | Ryujinx.Core/OsHle/Handles/KThread.cs | 151 |
1 files changed, 121 insertions, 30 deletions
diff --git a/Ryujinx.Core/OsHle/Handles/KThread.cs b/Ryujinx.Core/OsHle/Handles/KThread.cs index 2084c2ba..1a044665 100644 --- a/Ryujinx.Core/OsHle/Handles/KThread.cs +++ b/Ryujinx.Core/OsHle/Handles/KThread.cs @@ -7,9 +7,13 @@ namespace Ryujinx.Core.OsHle.Handles { public AThread Thread { get; private set; } + public int CoreMask { get; set; } + public long MutexAddress { get; set; } public long CondVarAddress { get; set; } + private Process Process; + public KThread NextMutexThread { get; set; } public KThread NextCondVarThread { get; set; } @@ -18,16 +22,24 @@ namespace Ryujinx.Core.OsHle.Handles public int ActualPriority { get; private set; } public int WantedPriority { get; private set; } - public int ProcessorId { get; private set; } + public int IdealCore { get; private set; } + public int ActualCore { get; set; } public int WaitHandle { get; set; } public int ThreadId => Thread.ThreadId; - public KThread(AThread Thread, int ProcessorId, int Priority) + public KThread( + AThread Thread, + Process Process, + int IdealCore, + int Priority) { - this.Thread = Thread; - this.ProcessorId = ProcessorId; + this.Thread = Thread; + this.Process = Process; + this.IdealCore = IdealCore; + + CoreMask = 1 << IdealCore; ActualPriority = WantedPriority = Priority; } @@ -54,59 +66,138 @@ namespace Ryujinx.Core.OsHle.Handles { ActualPriority = CurrPriority; - UpdateWaitList(); + UpdateWaitLists(); MutexOwner?.UpdatePriority(); } } - private void UpdateWaitList() + private void UpdateWaitLists() + { + UpdateMutexList(); + UpdateCondVarList(); + + Process.Scheduler.Resort(this); + } + + private void UpdateMutexList() { KThread OwnerThread = MutexOwner; - if (OwnerThread != null) + if (OwnerThread == null) { - //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) + 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) { - throw new InvalidOperationException(); + if (CurrThread.NextMutexThread == this) + { + CurrThread.NextMutexThread = NextMutexThread; + + break; + } + + CurrThread = CurrThread.NextMutexThread; } - lock (OwnerThread) - { - //Remove itself from the list. - KThread CurrThread = OwnerThread; + //Re-add taking new priority into account. + CurrThread = OwnerThread; - while (CurrThread.NextMutexThread != null) + while (CurrThread.NextMutexThread != null) + { + if (CurrThread.NextMutexThread.ActualPriority > ActualPriority) { - if (CurrThread.NextMutexThread == this) - { - CurrThread.NextMutexThread = NextMutexThread; + break; + } - break; - } + CurrThread = CurrThread.NextMutexThread; + } - CurrThread = CurrThread.NextMutexThread; - } + NextMutexThread = CurrThread.NextMutexThread; - //Re-add taking new priority into account. - CurrThread = OwnerThread; + CurrThread.NextMutexThread = this; + } + } - while (CurrThread.NextMutexThread != null) + private void UpdateCondVarList() + { + lock (Process.ThreadArbiterListLock) + { + 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.NextMutexThread.ActualPriority < ActualPriority) + if (CurrThread.NextCondVarThread == this) { + CurrThread.NextCondVarThread = NextCondVarThread; + + Found = true; + break; } - CurrThread = CurrThread.NextMutexThread; + CurrThread = CurrThread.NextCondVarThread; } + } - NextMutexThread = CurrThread.NextMutexThread; + if (!Found) + { + return; + } + + //Re-add taking new priority into account. + if (Process.ThreadArbiterListHead == null || + Process.ThreadArbiterListHead.ActualPriority > ActualPriority) + { + NextCondVarThread = Process.ThreadArbiterListHead; + + Process.ThreadArbiterListHead = this; - CurrThread.NextMutexThread = this; + return; } + + CurrThread = Process.ThreadArbiterListHead; + + while (CurrThread.NextCondVarThread != null) + { + if (CurrThread.NextCondVarThread.ActualPriority > ActualPriority) + { + break; + } + + CurrThread = CurrThread.NextCondVarThread; + } + + NextCondVarThread = CurrThread.NextCondVarThread; + + CurrThread.NextCondVarThread = this; } } } |
