diff --git a/Ryujinx.HLE/HOS/Kernel/Common/KTimeManager.cs b/Ryujinx.HLE/HOS/Kernel/Common/KTimeManager.cs
index f7a1c24adc..4eb736f2cd 100644
--- a/Ryujinx.HLE/HOS/Kernel/Common/KTimeManager.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Common/KTimeManager.cs
@@ -8,6 +8,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
 {
     class KTimeManager : IDisposable
     {
+        public static readonly long DefaultTimeIncrementNanoseconds = ConvertGuestTicksToNanoseconds(2);
+
         private class WaitingObject
         {
             public IKFutureSchedulerObject Object { get; }
@@ -24,6 +26,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
         private readonly List<WaitingObject> _waitingObjects;
         private AutoResetEvent _waitEvent;
         private bool _keepRunning;
+        private long _enforceWakeupFromSpinWait;
 
         public KTimeManager(KernelContext context)
         {
@@ -41,11 +44,16 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
 
         public void ScheduleFutureInvocation(IKFutureSchedulerObject schedulerObj, long timeout)
         {
-            long timePoint = PerformanceCounter.ElapsedMilliseconds + ConvertNanosecondsToMilliseconds(timeout);
+            long timePoint = PerformanceCounter.ElapsedTicks + ConvertNanosecondsToHostTicks(timeout);
 
             lock (_context.CriticalSection.Lock)
             {
                 _waitingObjects.Add(new WaitingObject(schedulerObj, timePoint));
+
+                if (timeout < 1000000)
+                {
+                    Interlocked.Exchange(ref _enforceWakeupFromSpinWait, 1);
+                }
             }
 
             _waitEvent.Set();
@@ -61,27 +69,51 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
 
         private void WaitAndCheckScheduledObjects()
         {
+            SpinWait spinWait = new SpinWait();
+            WaitingObject next;
+
             using (_waitEvent = new AutoResetEvent(false))
             {
                 while (_keepRunning)
                 {
-                    WaitingObject next;
-
                     lock (_context.CriticalSection.Lock)
                     {
+                        Interlocked.Exchange(ref _enforceWakeupFromSpinWait, 0);
+
                         next = _waitingObjects.OrderBy(x => x.TimePoint).FirstOrDefault();
                     }
 
                     if (next != null)
                     {
-                        long timePoint = PerformanceCounter.ElapsedMilliseconds;
+                        long timePoint = PerformanceCounter.ElapsedTicks;
 
                         if (next.TimePoint > timePoint)
                         {
-                            _waitEvent.WaitOne((int)(next.TimePoint - timePoint));
+                            long ms = Math.Min((next.TimePoint - timePoint) / PerformanceCounter.TicksPerMillisecond, int.MaxValue);
+
+                            if (ms > 0)
+                            {
+                                _waitEvent.WaitOne((int)ms);
+                            }
+                            else
+                            {
+                                while (Interlocked.Read(ref _enforceWakeupFromSpinWait) != 1 && PerformanceCounter.ElapsedTicks <= next.TimePoint)
+                                {
+                                    if (spinWait.NextSpinWillYield)
+                                    {
+                                        Thread.Yield();
+
+                                        spinWait.Reset();
+                                    }
+
+                                    spinWait.SpinOnce();
+                                }
+
+                                spinWait.Reset();
+                            }
                         }
 
-                        bool timeUp = PerformanceCounter.ElapsedMilliseconds >= next.TimePoint;
+                        bool timeUp = PerformanceCounter.ElapsedTicks >= next.TimePoint;
 
                         if (timeUp)
                         {
@@ -119,6 +151,22 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
             return time * 1000000;
         }
 
+        public static long ConvertNanosecondsToHostTicks(long ns)
+        {
+            long nsDiv = ns / 1000000000;
+            long nsMod = ns % 1000000000;
+            long tickDiv = PerformanceCounter.TicksPerSecond / 1000000000;
+            long tickMod = PerformanceCounter.TicksPerSecond % 1000000000;
+
+            long baseTicks = (nsMod * tickMod + PerformanceCounter.TicksPerSecond - 1) / 1000000000;
+            return (nsDiv * tickDiv) * 1000000000 + nsDiv * tickMod + nsMod * tickDiv + baseTicks;
+        }
+
+        public static long ConvertGuestTicksToNanoseconds(long ticks)
+        {
+            return (long)Math.Ceiling(ticks * (1000000000.0 / 19200000.0));
+        }
+
         public static long ConvertHostTicksToTicks(long time)
         {
             return (long)((time / (double)PerformanceCounter.TicksPerSecond) * 19200000.0);
diff --git a/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs b/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs
index f7b3215f92..8d0d818779 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<KServerSession>(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<KServerSession>(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