From 7b040e51b078a16e979ad962ba1265f3be4bcb1d Mon Sep 17 00:00:00 2001 From: Mary Date: Sun, 28 Nov 2021 13:15:26 +0100 Subject: kernel: Fix sleep timing accuracy (#2828) * kernel: Fix sleep timing accuracy This commit corrects some mistake while comparing reversing of kernel 13.x with our own. WaitAndCheckScheduledObjects timing accuracy was also improved. * Make KTimeManager.WaitAndCheckScheduledObjects spin wait for sub milliseconds Fix performance regression on Pokemon Let's Go games and possibly others. * Address rip's comment * kernel: Fix issues with timeout of -1 (0xFFFFFFFF) Fixes possible hang on Pokemon DP and possibly others --- Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs | 32 +++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'Ryujinx.HLE/HOS/Kernel/SupervisorCall') diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs index f7b3215f..8d0d8187 100644 --- a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs +++ b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs @@ -506,6 +506,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall return KernelResult.UserCopyFailed; } + if (timeout > 0) + { + timeout += KTimeManager.DefaultTimeIncrementNanoseconds; + } + return ReplyAndReceive(handles, replyTargetHandle, timeout, out handleIndex); } @@ -547,6 +552,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall if (result == KernelResult.Success) { + if (timeout > 0) + { + timeout += KTimeManager.DefaultTimeIncrementNanoseconds; + } + while ((result = _context.Synchronization.WaitFor(syncObjs, timeout, out handleIndex)) == KernelResult.Success) { KServerSession session = currentProcess.HandleTable.GetObject(handles[handleIndex]); @@ -644,6 +654,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall if (result == KernelResult.Success) { + if (timeout > 0) + { + timeout += KTimeManager.DefaultTimeIncrementNanoseconds; + } + while ((result = _context.Synchronization.WaitFor(syncObjs, timeout, out handleIndex)) == KernelResult.Success) { KServerSession session = currentProcess.HandleTable.GetObject(handles[handleIndex]); @@ -2117,7 +2132,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall } else { - KernelStatic.GetCurrentThread().Sleep(timeout); + KernelStatic.GetCurrentThread().Sleep(timeout + KTimeManager.DefaultTimeIncrementNanoseconds); } } @@ -2458,6 +2473,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall } } + if (timeout > 0) + { + timeout += KTimeManager.DefaultTimeIncrementNanoseconds; + } + KernelResult result = _context.Synchronization.WaitFor(syncObjs, timeout, out handleIndex); if (result == KernelResult.PortRemoteClosed) @@ -2541,6 +2561,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall KProcess currentProcess = KernelStatic.GetCurrentProcess(); + if (timeout > 0) + { + timeout += KTimeManager.DefaultTimeIncrementNanoseconds; + } + return currentProcess.AddressArbiter.WaitProcessWideKeyAtomic( mutexAddress, condVarAddress, @@ -2571,6 +2596,11 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall KProcess currentProcess = KernelStatic.GetCurrentProcess(); + if (timeout > 0) + { + timeout += KTimeManager.DefaultTimeIncrementNanoseconds; + } + return type switch { ArbitrationType.WaitIfLessThan -- cgit v1.2.3