ryujinx-mirror/Ryujinx.HLE/HOS/Kernel/SupervisorCall/SyscallHandler.cs
Mary e96ef6d532
kernel: Implement thread pinning support (#2840)
* kernel: Implement Thread pinning support

This commit adds support for 8.x thread pinning changes and implement SynchronizePreemptionState syscall.

Based on kernel 13.x reverse.

* Address gdkchan's comment

* kernel: fix missing critical section leave in SetActivity

Fix Unity games

* Implement missing bits on the interrupt handler and inline update pinning function as it cannot be generic

* Fix some bugs in SetActivity and SetCoreAndAffinityMask

* Address gdkchan's comments
2021-12-30 10:55:06 +01:00

65 lines
No EOL
1.9 KiB
C#

using ARMeilleure.State;
using Ryujinx.HLE.HOS.Kernel.Threading;
using System;
namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
{
partial class SyscallHandler
{
private readonly KernelContext _context;
private readonly Syscall32 _syscall32;
private readonly Syscall64 _syscall64;
public SyscallHandler(KernelContext context)
{
_context = context;
_syscall32 = new Syscall32(context.Syscall);
_syscall64 = new Syscall64(context.Syscall);
}
public void SvcCall(object sender, InstExceptionEventArgs e)
{
KThread currentThread = KernelStatic.GetCurrentThread();
if (currentThread.Owner != null &&
currentThread.GetUserDisableCount() != 0 &&
currentThread.Owner.PinnedThreads[currentThread.CurrentCore] == null)
{
_context.CriticalSection.Enter();
currentThread.Owner.PinThread(currentThread);
currentThread.SetUserInterruptFlag();
_context.CriticalSection.Leave();
}
ExecutionContext context = (ExecutionContext)sender;
if (context.IsAarch32)
{
var svcFunc = SyscallTable.SvcTable32[e.Id];
if (svcFunc == null)
{
throw new NotImplementedException($"SVC 0x{e.Id:X4} is not implemented.");
}
svcFunc(_syscall32, context);
}
else
{
var svcFunc = SyscallTable.SvcTable64[e.Id];
if (svcFunc == null)
{
throw new NotImplementedException($"SVC 0x{e.Id:X4} is not implemented.");
}
svcFunc(_syscall64, context);
}
currentThread.HandlePostSyscall();
}
}
}