aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
diff options
context:
space:
mode:
authormpnico <mpnico@gmail.com>2021-09-11 22:08:25 +0200
committerGitHub <noreply@github.com>2021-09-11 22:08:25 +0200
commit117e32a6fffc30cdb895aa98483af7df353a8dd1 (patch)
tree3a6ad3b396bbf641663dada2419709837f7c8268 /Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
parentb0e410a828fd37bf0d9021fc2f6b630e3944a861 (diff)
Implement a "Pause Emulation" option & hotkey (#2428)
* Add a "Pause Emulation" option and hotkey Closes Ryujinx#1604 * Refactoring how pause is handled * Applied suggested changes from review * Applied suggested fixes * Pass correct suspend type to threads for suspend/resume * Fix NRE after stoping emulation * Removing SimulateWakeUpMessage call after resuming emulation * Skip suspending non game process * Pause the tickCounter in the ExecutionContext * Refactoring tickCounter pause/resume as suggested * Fix Config migration to add pause hotkey * Fixed pausing only application threads * Fix exiting emulator while paused * Avoid pause/resume while already paused/resumed * Cleanup unused code * Avoid restarting audio if stopping emulation while in pause. * Added suggested changes * Fix ConfigurationState
Diffstat (limited to 'Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs')
-rw-r--r--Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs67
1 files changed, 40 insertions, 27 deletions
diff --git a/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
index 7224cca1..396a79ba 100644
--- a/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
+++ b/Ryujinx.HLE/HOS/Kernel/Threading/KThread.cs
@@ -471,6 +471,29 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
KernelContext.CriticalSection.Leave();
}
+ public void Suspend(ThreadSchedState type)
+ {
+ _forcePauseFlags |= type;
+
+ CombineForcePauseFlags();
+ }
+
+ public void Resume(ThreadSchedState type)
+ {
+ ThreadSchedState oldForcePauseFlags = _forcePauseFlags;
+
+ _forcePauseFlags &= ~type;
+
+ if ((oldForcePauseFlags & ~type) == ThreadSchedState.None)
+ {
+ ThreadSchedState oldSchedFlags = SchedFlags;
+
+ SchedFlags &= ThreadSchedState.LowMask;
+
+ AdjustScheduling(oldSchedFlags);
+ }
+ }
+
public KernelResult SetActivity(bool pause)
{
KernelResult result = KernelResult.Success;
@@ -495,9 +518,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
// Pause, the force pause flag should be clear (thread is NOT paused).
if ((_forcePauseFlags & ThreadSchedState.ThreadPauseFlag) == 0)
{
- _forcePauseFlags |= ThreadSchedState.ThreadPauseFlag;
-
- CombineForcePauseFlags();
+ Suspend(ThreadSchedState.ThreadPauseFlag);
}
else
{
@@ -509,18 +530,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
// Unpause, the force pause flag should be set (thread is paused).
if ((_forcePauseFlags & ThreadSchedState.ThreadPauseFlag) != 0)
{
- ThreadSchedState oldForcePauseFlags = _forcePauseFlags;
-
- _forcePauseFlags &= ~ThreadSchedState.ThreadPauseFlag;
-
- if ((oldForcePauseFlags & ~ThreadSchedState.ThreadPauseFlag) == ThreadSchedState.None)
- {
- ThreadSchedState oldSchedFlags = SchedFlags;
-
- SchedFlags &= ThreadSchedState.LowMask;
-
- AdjustScheduling(oldSchedFlags);
- }
+ Resume(ThreadSchedState.ThreadPauseFlag);
}
else
{
@@ -832,19 +842,22 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
if (!IsSchedulable)
{
- // Ensure our thread is running and we have an event.
- StartHostThread();
-
- // If the thread is not schedulable, we want to just run or pause
- // it directly as we don't care about priority or the core it is
- // running on in this case.
- if (SchedFlags == ThreadSchedState.Running)
- {
- _schedulerWaitEvent.Set();
- }
- else
+ if (!_forcedUnschedulable)
{
- _schedulerWaitEvent.Reset();
+ // Ensure our thread is running and we have an event.
+ StartHostThread();
+
+ // If the thread is not schedulable, we want to just run or pause
+ // it directly as we don't care about priority or the core it is
+ // running on in this case.
+ if (SchedFlags == ThreadSchedState.Running)
+ {
+ _schedulerWaitEvent.Set();
+ }
+ else
+ {
+ _schedulerWaitEvent.Reset();
+ }
}
return;