| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- using ChocolArm64;
- using System;
- namespace Ryujinx.Core.OsHle.Handles
- {
- class KThread : KSynchronizationObject
- {
- 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; }
- public KThread MutexOwner { get; set; }
- public int ActualPriority { get; private set; }
- public int WantedPriority { 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,
- Process Process,
- int IdealCore,
- int Priority)
- {
- this.Thread = Thread;
- this.Process = Process;
- this.IdealCore = IdealCore;
- CoreMask = 1 << IdealCore;
- ActualPriority = WantedPriority = Priority;
- }
- public void SetPriority(int Priority)
- {
- WantedPriority = Priority;
- UpdatePriority();
- }
- public void UpdatePriority()
- {
- int OldPriority = ActualPriority;
- int CurrPriority = WantedPriority;
- if (NextMutexThread != null && CurrPriority > NextMutexThread.WantedPriority)
- {
- CurrPriority = NextMutexThread.WantedPriority;
- }
- if (CurrPriority != OldPriority)
- {
- 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)
- {
- if (CurrThread.NextMutexThread == this)
- {
- CurrThread.NextMutexThread = NextMutexThread;
- break;
- }
- 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 (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;
- }
- NextCondVarThread = CurrThread.NextCondVarThread;
- CurrThread.NextCondVarThread = this;
- }
- }
- }
- }
|