aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Core/OsHle/Handles/KThread.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-05-13 00:22:42 -0300
committergdkchan <gab.dark.100@gmail.com>2018-05-13 00:22:42 -0300
commit4546d1b9be1052bbf82858d97795b33355bf64da (patch)
treea88286d145d8da522a81b3a265c538e7795b7f8d /Ryujinx.Core/OsHle/Handles/KThread.cs
parent3603497a137d14f2d65c5450133f2486a9f9620c (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.cs151
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;
}
}
}