diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-04-25 23:11:26 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-04-25 23:12:26 -0300 |
| commit | a38a72b0622f89897bdcd01b6d00ea6bc142c34f (patch) | |
| tree | 2025cdddaa7ef6769ac69c51eeede0924ffcba5f /Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs | |
| parent | 211f7f69db4d84b82caa3ee62d4ecdfbbd95604d (diff) | |
Some small sync primitive fixes, logging fixes, started to implement the 2D engine on the GPU, fixed DrawArrays, implemented a few more shader instructions, made a start on nvdrv refactor, etc...
Diffstat (limited to 'Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs')
| -rw-r--r-- | Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs b/Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs index d5593e02..ec109b2d 100644 --- a/Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs +++ b/Ryujinx.Core/OsHle/Kernel/SvcThreadSync.cs @@ -18,6 +18,11 @@ namespace Ryujinx.Core.OsHle.Kernel long MutexAddress = (long)ThreadState.X1; int WaitThreadHandle = (int)ThreadState.X2; + Ns.Log.PrintDebug(LogClass.KernelSvc, + "OwnerThreadHandle = " + OwnerThreadHandle.ToString("x8") + ", " + + "MutexAddress = " + MutexAddress .ToString("x16") + ", " + + "WaitThreadHandle = " + WaitThreadHandle .ToString("x8")); + if (IsPointingInsideKernel(MutexAddress)) { Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid mutex address 0x{MutexAddress:x16}!"); @@ -38,6 +43,8 @@ namespace Ryujinx.Core.OsHle.Kernel KThread OwnerThread = Process.HandleTable.GetData<KThread>(OwnerThreadHandle); + Ns.Log.PrintDebug(LogClass.KernelSvc, "lock tid: " + OwnerThread.ThreadId.ToString()); + if (OwnerThread == null) { Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid owner thread handle 0x{OwnerThreadHandle:x8}!"); @@ -69,6 +76,8 @@ namespace Ryujinx.Core.OsHle.Kernel { long MutexAddress = (long)ThreadState.X0; + Ns.Log.PrintDebug(LogClass.KernelSvc, "MutexAddress = " + MutexAddress.ToString("x16")); + if (IsPointingInsideKernel(MutexAddress)) { Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid mutex address 0x{MutexAddress:x16}!"); @@ -102,6 +111,12 @@ namespace Ryujinx.Core.OsHle.Kernel int ThreadHandle = (int)ThreadState.X2; ulong Timeout = ThreadState.X3; + Ns.Log.PrintDebug(LogClass.KernelSvc, + "OwnerThreadHandle = " + MutexAddress .ToString("x16") + ", " + + "MutexAddress = " + CondVarAddress.ToString("x16") + ", " + + "WaitThreadHandle = " + ThreadHandle .ToString("x8") + ", " + + "Timeout = " + Timeout .ToString("x16")); + if (IsPointingInsideKernel(MutexAddress)) { Ns.Log.PrintWarning(LogClass.KernelSvc, $"Invalid mutex address 0x{MutexAddress:x16}!"); @@ -166,6 +181,8 @@ namespace Ryujinx.Core.OsHle.Kernel { int MutexValue = Process.Memory.ReadInt32(MutexAddress); + Ns.Log.PrintDebug(LogClass.KernelSvc, "MutexValue = " + MutexValue.ToString("x8")); + if (MutexValue != (OwnerThreadHandle | MutexHasListenersMask)) { return; @@ -176,7 +193,7 @@ namespace Ryujinx.Core.OsHle.Kernel InsertWaitingMutexThread(OwnerThreadHandle, WaitThread); - Process.Scheduler.EnterWait(WaitThread); + Process.Scheduler.EnterWait(CurrThread); } private bool MutexUnlock(KThread CurrThread, long MutexAddress) @@ -199,8 +216,12 @@ namespace Ryujinx.Core.OsHle.Kernel OwnerThread = OwnerThread.NextMutexThread; } + UpdateMutexOwner(CurrThread, OwnerThread, MutexAddress); + CurrThread.NextMutexThread = null; + CurrThread.UpdatePriority(); + if (OwnerThread != null) { int HasListeners = OwnerThread.NextMutexThread != null ? MutexHasListenersMask : 0; @@ -284,7 +305,9 @@ namespace Ryujinx.Core.OsHle.Kernel } else { - return Process.Scheduler.EnterWait(WaitThread); + Process.Scheduler.EnterWait(WaitThread); + + return true; } } @@ -314,8 +337,6 @@ namespace Ryujinx.Core.OsHle.Kernel int MutexValue = Process.Memory.ReadInt32(CurrThread.MutexAddress); - MutexValue &= ~MutexHasListenersMask; - if (MutexValue == 0) { //Give the lock to this thread. @@ -325,15 +346,17 @@ namespace Ryujinx.Core.OsHle.Kernel CurrThread.MutexAddress = 0; CurrThread.CondVarAddress = 0; - CurrThread.MutexOwner = null; + CurrThread.MutexOwner?.UpdatePriority(); - CurrThread.UpdatePriority(); + CurrThread.MutexOwner = null; Process.Scheduler.WakeUp(CurrThread); } else { //Wait until the lock is released. + MutexValue &= ~MutexHasListenersMask; + InsertWaitingMutexThread(MutexValue, CurrThread); MutexValue |= MutexHasListenersMask; @@ -399,6 +422,23 @@ namespace Ryujinx.Core.OsHle.Kernel OwnerThread.UpdatePriority(); } + private void UpdateMutexOwner(KThread CurrThread, KThread NewOwner, long MutexAddress) + { + //Go through all threads waiting for the mutex, + //and update the MutexOwner field to point to the new owner. + CurrThread = CurrThread.NextMutexThread; + + while (CurrThread != null) + { + if (CurrThread.MutexAddress == MutexAddress) + { + CurrThread.MutexOwner = NewOwner; + } + + CurrThread = CurrThread.NextMutexThread; + } + } + private void AcquireMutexValue(long MutexAddress) { while (!Process.Memory.AcquireAddress(MutexAddress)) |
