Improve kernel IPC implementation (#550)
* Implement some IPC related kernel SVCs properly * Fix BLZ decompression when the segment also has a uncompressed chunck * Set default cpu core on process start from ProgramLoader, remove debug message * Load process capabilities properly on KIPs * Fix a copy/paste error in UnmapPhysicalMemory64 * Implement smarter switching between old and new IPC system to support the old HLE services implementation without the manual switch * Implement RegisterService on sm and AcceptSession (partial) * Misc fixes and improvements on new IPC methods * Move IPC related SVCs into a separate file, and logging on RegisterService (sm) * Some small fixes related to receive list buffers and error cases * Load NSOs using the correct pool partition * Fix corner case on GetMaskFromMinMax where range is 64, doesn't happen in pratice however * Fix send static buffer copy * Session release, implement closing requests on client disconnect * Implement ConnectToPort SVC * KLightSession init
This commit is contained in:
parent
3731d0ce84
commit
22bacc6188
51 changed files with 4310 additions and 840 deletions
|
@ -1,4 +1,6 @@
|
|||
using Ryujinx.HLE.HOS.Kernel.Common;
|
||||
using Ryujinx.HLE.HOS.Kernel.Process;
|
||||
using Ryujinx.HLE.HOS.Services;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
||||
{
|
||||
|
@ -10,12 +12,116 @@ namespace Ryujinx.HLE.HOS.Kernel.Ipc
|
|||
|
||||
private KPort _parent;
|
||||
|
||||
public KClientPort(Horizon system) : base(system) { }
|
||||
public bool IsLight => _parent.IsLight;
|
||||
|
||||
public void Initialize(KPort parent, int maxSessions)
|
||||
private object _countIncLock;
|
||||
|
||||
//TODO: Remove that, we need it for now to allow HLE
|
||||
//SM implementation to work with the new IPC system.
|
||||
public IpcService Service { get; set; }
|
||||
|
||||
public KClientPort(Horizon system, KPort parent, int maxSessions) : base(system)
|
||||
{
|
||||
_maxSessions = maxSessions;
|
||||
_parent = parent;
|
||||
|
||||
_countIncLock = new object();
|
||||
}
|
||||
|
||||
public KernelResult Connect(out KClientSession clientSession)
|
||||
{
|
||||
clientSession = null;
|
||||
|
||||
KProcess currentProcess = System.Scheduler.GetCurrentProcess();
|
||||
|
||||
if (currentProcess.ResourceLimit != null &&
|
||||
!currentProcess.ResourceLimit.Reserve(LimitableResource.Session, 1))
|
||||
{
|
||||
return KernelResult.ResLimitExceeded;
|
||||
}
|
||||
|
||||
lock (_countIncLock)
|
||||
{
|
||||
if (_sessionsCount < _maxSessions)
|
||||
{
|
||||
_sessionsCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcess.ResourceLimit?.Release(LimitableResource.Session, 1);
|
||||
|
||||
return KernelResult.SessionCountExceeded;
|
||||
}
|
||||
|
||||
if (_currentCapacity < _sessionsCount)
|
||||
{
|
||||
_currentCapacity = _sessionsCount;
|
||||
}
|
||||
}
|
||||
|
||||
KSession session = new KSession(System);
|
||||
|
||||
if (Service != null)
|
||||
{
|
||||
session.ClientSession.Service = Service;
|
||||
}
|
||||
|
||||
KernelResult result = _parent.EnqueueIncomingSession(session.ServerSession);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
{
|
||||
session.ClientSession.DecrementReferenceCount();
|
||||
session.ServerSession.DecrementReferenceCount();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
clientSession = session.ClientSession;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public KernelResult ConnectLight(out KLightClientSession clientSession)
|
||||
{
|
||||
clientSession = null;
|
||||
|
||||
KProcess currentProcess = System.Scheduler.GetCurrentProcess();
|
||||
|
||||
if (currentProcess.ResourceLimit != null &&
|
||||
!currentProcess.ResourceLimit.Reserve(LimitableResource.Session, 1))
|
||||
{
|
||||
return KernelResult.ResLimitExceeded;
|
||||
}
|
||||
|
||||
lock (_countIncLock)
|
||||
{
|
||||
if (_sessionsCount < _maxSessions)
|
||||
{
|
||||
_sessionsCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentProcess.ResourceLimit?.Release(LimitableResource.Session, 1);
|
||||
|
||||
return KernelResult.SessionCountExceeded;
|
||||
}
|
||||
}
|
||||
|
||||
KLightSession session = new KLightSession(System);
|
||||
|
||||
KernelResult result = _parent.EnqueueIncomingLightSession(session.ServerSession);
|
||||
|
||||
if (result != KernelResult.Success)
|
||||
{
|
||||
session.ClientSession.DecrementReferenceCount();
|
||||
session.ServerSession.DecrementReferenceCount();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
clientSession = session.ClientSession;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public new static KernelResult RemoveName(Horizon system, string name)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue