Initial work to support changing thread core on the scheduler, also some cond var priority fixes
This commit is contained in:
parent
3603497a13
commit
4546d1b9be
9 changed files with 442 additions and 199 deletions
|
@ -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)
|
||||
break;
|
||||
}
|
||||
|
||||
CurrThread = CurrThread.NextMutexThread;
|
||||
}
|
||||
|
||||
NextMutexThread = CurrThread.NextMutexThread;
|
||||
|
||||
CurrThread.NextMutexThread = this;
|
||||
}
|
||||
}
|
||||
|
||||
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.NextCondVarThread == this)
|
||||
{
|
||||
CurrThread.NextMutexThread = NextMutexThread;
|
||||
CurrThread.NextCondVarThread = NextCondVarThread;
|
||||
|
||||
Found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
CurrThread = CurrThread.NextMutexThread;
|
||||
CurrThread = CurrThread.NextCondVarThread;
|
||||
}
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
NextCondVarThread = CurrThread.NextCondVarThread;
|
||||
|
||||
CurrThread.NextCondVarThread = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue