Allow more than one process, free resources on process dispose, implement SvcExitThread

This commit is contained in:
gdkchan 2018-03-12 01:04:52 -03:00
parent 3aaa4717b6
commit 7a27990faa
46 changed files with 926 additions and 598 deletions

View file

@ -1,12 +1,13 @@
using ChocolArm64.Events;
using ChocolArm64.Memory;
using ChocolArm64.State;
using Ryujinx.Core.OsHle.Handles;
using System;
using System.Collections.Generic;
namespace Ryujinx.Core.OsHle.Svc
{
partial class SvcHandler
partial class SvcHandler : IDisposable
{
private delegate void SvcFunc(AThreadState ThreadState);
@ -16,10 +17,12 @@ namespace Ryujinx.Core.OsHle.Svc
private Process Process;
private AMemory Memory;
private static Random Rng;
private HashSet<(HSharedMem, long)> MappedSharedMems;
private ulong CurrentHeapSize;
private static Random Rng;
public SvcHandler(Switch Ns, Process Process)
{
SvcFuncs = new Dictionary<int, SvcFunc>()
@ -32,6 +35,7 @@ namespace Ryujinx.Core.OsHle.Svc
{ 0x07, SvcExitProcess },
{ 0x08, SvcCreateThread },
{ 0x09, SvcStartThread },
{ 0x0a, SvcExitThread },
{ 0x0b, SvcSleepThread },
{ 0x0c, SvcGetThreadPriority },
{ 0x0d, SvcSetThreadPriority },
@ -60,6 +64,8 @@ namespace Ryujinx.Core.OsHle.Svc
this.Ns = Ns;
this.Process = Process;
this.Memory = Process.Memory;
MappedSharedMems = new HashSet<(HSharedMem, long)>();
}
static SvcHandler()
@ -84,5 +90,26 @@ namespace Ryujinx.Core.OsHle.Svc
throw new NotImplementedException(e.Id.ToString("x4"));
}
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool Disposing)
{
if (Disposing)
{
lock (MappedSharedMems)
{
foreach ((HSharedMem SharedMem, long Position) in MappedSharedMems)
{
SharedMem.RemoveVirtualPosition(Memory, Position);
}
MappedSharedMems.Clear();
}
}
}
}
}

View file

@ -165,7 +165,7 @@ namespace Ryujinx.Core.OsHle.Svc
return;
}
HSharedMem SharedMem = Ns.Os.Handles.GetData<HSharedMem>(Handle);
HSharedMem SharedMem = Process.HandleTable.GetData<HSharedMem>(Handle);
if (SharedMem != null)
{
@ -175,7 +175,12 @@ namespace Ryujinx.Core.OsHle.Svc
Memory.Manager.Reprotect(Src, Size, (AMemoryPerm)Perm);
SharedMem.AddVirtualPosition(Src);
lock (MappedSharedMems)
{
MappedSharedMems.Add((SharedMem, Src));
}
SharedMem.AddVirtualPosition(Memory, Src);
ThreadState.X0 = 0;
}
@ -198,12 +203,19 @@ namespace Ryujinx.Core.OsHle.Svc
return;
}
HSharedMem HndData = Ns.Os.Handles.GetData<HSharedMem>(Handle);
HSharedMem SharedMem = Process.HandleTable.GetData<HSharedMem>(Handle);
if (HndData != null)
if (SharedMem != null)
{
Memory.Manager.Unmap(Src, Size, (int)MemoryType.SharedMemory);
SharedMem.RemoveVirtualPosition(Memory, Src);
lock (MappedSharedMems)
{
MappedSharedMems.Remove((SharedMem, Src));
}
ThreadState.X0 = 0;
}
@ -229,12 +241,12 @@ namespace Ryujinx.Core.OsHle.Svc
Memory.Manager.Reprotect(Src, Size, (AMemoryPerm)Perm);
HTransferMem HndData = new HTransferMem(Memory, MapInfo.Perm, Src, Size);
HTransferMem TMem = new HTransferMem(Memory, MapInfo.Perm, Src, Size);
int Handle = Ns.Os.Handles.GenerateId(HndData);
ThreadState.X1 = (ulong)Handle;
ulong Handle = (ulong)Process.HandleTable.OpenHandle(TMem);
ThreadState.X0 = 0;
ThreadState.X1 = Handle;
}
private static bool IsValidPosition(long Position)

View file

@ -3,7 +3,6 @@ using ChocolArm64.State;
using Ryujinx.Core.OsHle.Exceptions;
using Ryujinx.Core.OsHle.Handles;
using Ryujinx.Core.OsHle.Ipc;
using Ryujinx.Core.OsHle.IpcServices;
using System;
using System.Threading;
@ -35,7 +34,7 @@ namespace Ryujinx.Core.OsHle.Svc
{
int Handle = (int)ThreadState.X0;
Ns.Os.CloseHandle(Handle);
Process.HandleTable.CloseHandle(Handle);
ThreadState.X0 = 0;
}
@ -80,10 +79,12 @@ namespace Ryujinx.Core.OsHle.Svc
//TODO: Validate that app has perms to access the service, and that the service
//actually exists, return error codes otherwise.
HSession Session = new HSession(ServiceFactory.MakeService(Name));
HSession Session = new HSession(Process.Services.GetService(Name));
ThreadState.X1 = (ulong)Ns.Os.Handles.GenerateId(Session);
ulong Handle = (ulong)Process.HandleTable.OpenHandle(Session);
ThreadState.X0 = 0;
ThreadState.X1 = Handle;
}
private void SvcSendSyncRequest(AThreadState ThreadState)
@ -119,13 +120,21 @@ namespace Ryujinx.Core.OsHle.Svc
byte[] CmdData = AMemoryHelper.ReadBytes(Memory, CmdPtr, (int)Size);
HSession Session = Ns.Os.Handles.GetData<HSession>(Handle);
HSession Session = Process.HandleTable.GetData<HSession>(Handle);
IpcMessage Cmd = new IpcMessage(CmdData, CmdPtr, Session is HDomain);
if (Session != null)
{
IpcHandler.IpcCall(Ns, Memory, Session, Cmd, ThreadState.ThreadId, CmdPtr, Handle);
IpcHandler.IpcCall(
Ns,
Process,
Memory,
Session,
Cmd,
ThreadState.ThreadId,
CmdPtr,
Handle);
byte[] Response = AMemoryHelper.ReadBytes(Memory, CmdPtr, (int)Size);

View file

@ -39,7 +39,7 @@ namespace Ryujinx.Core.OsHle.Svc
{
int Handle = (int)ThreadState.X0;
HThread Thread = Ns.Os.Handles.GetData<HThread>(Handle);
HThread Thread = Process.HandleTable.GetData<HThread>(Handle);
if (Thread != null)
{
@ -51,6 +51,13 @@ namespace Ryujinx.Core.OsHle.Svc
//TODO: Error codes.
}
private void SvcExitThread(AThreadState ThreadState)
{
HThread CurrThread = Process.GetThread(ThreadState.Tpidr);
CurrThread.Thread.StopExecution();
}
private void SvcSleepThread(AThreadState ThreadState)
{
ulong NanoSecs = ThreadState.X0;
@ -71,7 +78,7 @@ namespace Ryujinx.Core.OsHle.Svc
{
int Handle = (int)ThreadState.X1;
HThread Thread = Ns.Os.Handles.GetData<HThread>(Handle);
HThread Thread = Process.HandleTable.GetData<HThread>(Handle);
if (Thread != null)
{
@ -87,7 +94,7 @@ namespace Ryujinx.Core.OsHle.Svc
int Handle = (int)ThreadState.X1;
int Prio = (int)ThreadState.X0;
HThread Thread = Ns.Os.Handles.GetData<HThread>(Handle);
HThread Thread = Process.HandleTable.GetData<HThread>(Handle);
if (Thread != null)
{
@ -110,7 +117,7 @@ namespace Ryujinx.Core.OsHle.Svc
{
int Handle = (int)ThreadState.X0;
HThread Thread = Ns.Os.Handles.GetData<HThread>(Handle);
HThread Thread = Process.HandleTable.GetData<HThread>(Handle);
if (Thread != null)
{

View file

@ -13,7 +13,7 @@ namespace Ryujinx.Core.OsHle.Svc
long MutexAddress = (long)ThreadState.X1;
int RequestingThreadHandle = (int)ThreadState.X2;
HThread RequestingThread = Ns.Os.Handles.GetData<HThread>(RequestingThreadHandle);
HThread RequestingThread = Process.HandleTable.GetData<HThread>(RequestingThreadHandle);
Mutex M = new Mutex(Process, MutexAddress, OwnerThreadHandle);
@ -43,7 +43,7 @@ namespace Ryujinx.Core.OsHle.Svc
int ThreadHandle = (int)ThreadState.X2;
long Timeout = (long)ThreadState.X3;
HThread Thread = Ns.Os.Handles.GetData<HThread>(ThreadHandle);
HThread Thread = Process.HandleTable.GetData<HThread>(ThreadHandle);
Mutex M = new Mutex(Process, MutexAddress, ThreadHandle);