Make HLE disposable safely (#850)
* Make HLE disposable safely This fix the oldest issue with the HLE code: the kernel side disposability. Changelog: - Implement KProcess::UnpauseAndTerminateAllThreadsExcept, KThread::Terminate, KThread::TerminateCurrentProcess, KThread::PrepareForTermiation and the svc post handler accurately. - Implement svcTerminateProcess and svcExitProcess. (both untested) - Fix KHandleTable::Destroy not decrementing refcount of all objects stored in the table. - Spawn a custom KProcess with the maximum priority to terminate every guest KProcess. (terminating kernel emulation safely) - General system stability improvements to enhance the user's experience. * Fix a typo in a comment in KProcess.cs * Address gdk's comments
This commit is contained in:
parent
87bfe681ef
commit
55c956e2ec
7 changed files with 293 additions and 31 deletions
|
@ -1,5 +1,6 @@
|
|||
using ARMeilleure.State;
|
||||
using Ryujinx.HLE.HOS.Kernel.Process;
|
||||
using Ryujinx.HLE.HOS.Kernel.Threading;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
||||
|
@ -29,6 +30,15 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
ExecutionContext context = (ExecutionContext)sender;
|
||||
|
||||
svcFunc(this, context);
|
||||
|
||||
PostSvcHandler();
|
||||
}
|
||||
|
||||
private void PostSvcHandler()
|
||||
{
|
||||
KThread currentThread = _system.Scheduler.GetCurrentThread();
|
||||
|
||||
currentThread.HandlePostSyscall();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,9 +17,41 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
ExitProcess();
|
||||
}
|
||||
|
||||
public KernelResult TerminateProcess64(int handle)
|
||||
{
|
||||
return TerminateProcess(handle);
|
||||
}
|
||||
|
||||
private KernelResult TerminateProcess(int handle)
|
||||
{
|
||||
KProcess process = _process.HandleTable.GetObject<KProcess>(handle);
|
||||
|
||||
KernelResult result;
|
||||
|
||||
if (process != null)
|
||||
{
|
||||
if (process == _system.Scheduler.GetCurrentProcess())
|
||||
{
|
||||
result = KernelResult.Success;
|
||||
process.DecrementToZeroWhileTerminatingCurrent();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = process.Terminate();
|
||||
process.DecrementReferenceCount();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = KernelResult.InvalidHandle;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void ExitProcess()
|
||||
{
|
||||
_system.Scheduler.GetCurrentProcess().Terminate();
|
||||
_system.Scheduler.GetCurrentProcess().TerminateCurrentProcess();
|
||||
}
|
||||
|
||||
public KernelResult SignalEvent64(int handle)
|
||||
|
@ -184,6 +216,15 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
{
|
||||
currentThread.PrintGuestStackTrace();
|
||||
|
||||
// As the process is exiting, this is probably caused by emulation termination.
|
||||
if (currentThread.Owner.State == ProcessState.Exiting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Debug events.
|
||||
currentThread.Owner.TerminateCurrentProcess();
|
||||
|
||||
throw new GuestBrokeExecutionException();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -74,7 +74,8 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
|
|||
{ 0x72, nameof(SvcHandler.ConnectToPort64) },
|
||||
{ 0x73, nameof(SvcHandler.SetProcessMemoryPermission64) },
|
||||
{ 0x77, nameof(SvcHandler.MapProcessCodeMemory64) },
|
||||
{ 0x78, nameof(SvcHandler.UnmapProcessCodeMemory64) }
|
||||
{ 0x78, nameof(SvcHandler.UnmapProcessCodeMemory64) },
|
||||
{ 0x7B, nameof(SvcHandler.TerminateProcess64) }
|
||||
};
|
||||
|
||||
_svcTable64 = new Action<SvcHandler, ExecutionContext>[0x80];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue