Add events to shared memory, make it work better with direct memory
This commit is contained in:
parent
161193e113
commit
ebddc40550
7 changed files with 116 additions and 31 deletions
|
@ -1,13 +1,76 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Ryujinx.OsHle.Handles
|
namespace Ryujinx.OsHle.Handles
|
||||||
{
|
{
|
||||||
class HSharedMem
|
class HSharedMem
|
||||||
{
|
{
|
||||||
public long PhysPos { get; private set; }
|
private List<long> Positions;
|
||||||
public long VirtPos { get; set; }
|
|
||||||
|
public int PositionsCount => Positions.Count;
|
||||||
|
|
||||||
|
public EventHandler<EventArgs> MemoryMapped;
|
||||||
|
public EventHandler<EventArgs> MemoryUnmapped;
|
||||||
|
|
||||||
public HSharedMem(long PhysPos)
|
public HSharedMem(long PhysPos)
|
||||||
{
|
{
|
||||||
this.PhysPos = PhysPos;
|
Positions = new List<long>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddVirtualPosition(long Position)
|
||||||
|
{
|
||||||
|
lock (Positions)
|
||||||
|
{
|
||||||
|
Positions.Add(Position);
|
||||||
|
|
||||||
|
if (MemoryMapped != null)
|
||||||
|
{
|
||||||
|
MemoryMapped(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveVirtualPosition(long Position)
|
||||||
|
{
|
||||||
|
lock (Positions)
|
||||||
|
{
|
||||||
|
Positions.Remove(Position);
|
||||||
|
|
||||||
|
if (MemoryUnmapped != null)
|
||||||
|
{
|
||||||
|
MemoryUnmapped(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long GetVirtualPosition(int Index)
|
||||||
|
{
|
||||||
|
lock (Positions)
|
||||||
|
{
|
||||||
|
if (Index < 0 || Index >= Positions.Count)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Positions[Index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryGetLastVirtualPosition(out long Position)
|
||||||
|
{
|
||||||
|
lock (Positions)
|
||||||
|
{
|
||||||
|
if (Positions.Count > 0)
|
||||||
|
{
|
||||||
|
Position = Positions[Positions.Count - 1];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Position = 0;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -31,6 +31,8 @@ namespace Ryujinx.OsHle
|
||||||
|
|
||||||
private ConcurrentDictionary<int, Process> Processes;
|
private ConcurrentDictionary<int, Process> Processes;
|
||||||
|
|
||||||
|
private HSharedMem HidSharedMem;
|
||||||
|
|
||||||
private AMemoryAlloc Allocator;
|
private AMemoryAlloc Allocator;
|
||||||
|
|
||||||
private Switch Ns;
|
private Switch Ns;
|
||||||
|
@ -56,7 +58,12 @@ namespace Ryujinx.OsHle
|
||||||
HidOffset = Allocator.Alloc(HidSize);
|
HidOffset = Allocator.Alloc(HidSize);
|
||||||
FontOffset = Allocator.Alloc(FontSize);
|
FontOffset = Allocator.Alloc(FontSize);
|
||||||
|
|
||||||
HidHandle = Handles.GenerateId(new HSharedMem(HidOffset));
|
HidSharedMem = new HSharedMem(HidOffset);
|
||||||
|
|
||||||
|
HidSharedMem.MemoryMapped += HidInit;
|
||||||
|
|
||||||
|
HidHandle = Handles.GenerateId(HidSharedMem);
|
||||||
|
|
||||||
FontHandle = Handles.GenerateId(new HSharedMem(FontOffset));
|
FontHandle = Handles.GenerateId(new HSharedMem(FontOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +112,7 @@ namespace Ryujinx.OsHle
|
||||||
Processes.TryAdd(ProcessId, MainProcess);
|
Processes.TryAdd(ProcessId, MainProcess);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadProgram(string FileName)
|
public void LoadProgram(string FileName)
|
||||||
{
|
{
|
||||||
int ProcessId = IdGen.GenerateId();
|
int ProcessId = IdGen.GenerateId();
|
||||||
|
|
||||||
|
@ -139,18 +146,23 @@ namespace Ryujinx.OsHle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool ExitProcess(int ProcessId) {
|
internal bool ExitProcess(int ProcessId)
|
||||||
Process process;
|
{
|
||||||
var Success = Processes.TryRemove(ProcessId, out process);
|
bool Success = Processes.TryRemove(ProcessId, out Process Process);
|
||||||
if (Success) {
|
|
||||||
process.StopAllThreads();
|
if (Success)
|
||||||
|
{
|
||||||
|
Process.StopAllThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Processes.Count == 0) {
|
if (Processes.Count == 0)
|
||||||
|
{
|
||||||
Ns.OnFinish(EventArgs.Empty);
|
Ns.OnFinish(EventArgs.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool TryGetProcess(int ProcessId, out Process Process)
|
internal bool TryGetProcess(int ProcessId, out Process Process)
|
||||||
{
|
{
|
||||||
if (!Processes.TryGetValue(ProcessId, out Process))
|
if (!Processes.TryGetValue(ProcessId, out Process))
|
||||||
|
@ -176,11 +188,21 @@ namespace Ryujinx.OsHle
|
||||||
Handles.Delete(Handle);
|
Handles.Delete(Handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void HidInit(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
HSharedMem SharedMem = (HSharedMem)sender;
|
||||||
|
|
||||||
|
if (SharedMem.TryGetLastVirtualPosition(out long Position))
|
||||||
|
{
|
||||||
|
Logging.Info($"HID shared memory successfully mapped to {Position:x16}!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public long GetVirtHidOffset()
|
public long GetVirtHidOffset()
|
||||||
{
|
{
|
||||||
HSharedMem HidSharedMem = Handles.GetData<HSharedMem>(HidHandle);
|
HidSharedMem.TryGetLastVirtualPosition(out long Position);
|
||||||
|
|
||||||
return HidSharedMem.VirtPos;
|
return Position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -118,7 +118,7 @@ namespace Ryujinx.OsHle
|
||||||
{
|
{
|
||||||
if (MainThread != null)
|
if (MainThread != null)
|
||||||
{
|
{
|
||||||
if (MainThread.Thread.IsAlive)
|
while (MainThread.Thread.IsAlive)
|
||||||
{
|
{
|
||||||
MainThread.Thread.StopExecution();
|
MainThread.Thread.StopExecution();
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ namespace Ryujinx.OsHle
|
||||||
|
|
||||||
foreach (AThread Thread in TlsSlots.Values)
|
foreach (AThread Thread in TlsSlots.Values)
|
||||||
{
|
{
|
||||||
if (Thread.IsAlive)
|
while (Thread.IsAlive)
|
||||||
{
|
{
|
||||||
Thread.StopExecution();
|
Thread.StopExecution();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace Ryujinx.OsHle.Svc
|
||||||
partial class SvcHandler
|
partial class SvcHandler
|
||||||
{
|
{
|
||||||
private delegate void SvcFunc(ARegisters Registers);
|
private delegate void SvcFunc(ARegisters Registers);
|
||||||
|
|
||||||
private Dictionary<int, SvcFunc> SvcFuncs;
|
private Dictionary<int, SvcFunc> SvcFuncs;
|
||||||
|
|
||||||
private Switch Ns;
|
private Switch Ns;
|
||||||
|
|
|
@ -65,21 +65,18 @@ namespace Ryujinx.OsHle.Svc
|
||||||
|
|
||||||
private void SvcMapSharedMemory(ARegisters Registers)
|
private void SvcMapSharedMemory(ARegisters Registers)
|
||||||
{
|
{
|
||||||
int Handle = (int)Registers.X0;
|
int Handle = (int)Registers.X0;
|
||||||
long Position = (long)Registers.X1;
|
long Src = (long)Registers.X1;
|
||||||
long Size = (long)Registers.X2;
|
long Size = (long)Registers.X2;
|
||||||
int Perm = (int)Registers.X3;
|
int Perm = (int)Registers.X3;
|
||||||
|
|
||||||
HSharedMem HndData = Ns.Os.Handles.GetData<HSharedMem>(Handle);
|
HSharedMem SharedMem = Ns.Os.Handles.GetData<HSharedMem>(Handle);
|
||||||
|
|
||||||
if (HndData != null)
|
if (SharedMem != null)
|
||||||
{
|
{
|
||||||
long Src = Position;
|
SharedMem.AddVirtualPosition(Src);
|
||||||
long Dst = HndData.PhysPos;
|
|
||||||
|
|
||||||
HndData.VirtPos = Src;
|
Memory.Manager.MapPhys(Src, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm);
|
||||||
|
|
||||||
Memory.Manager.MapPhys(Position, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm);
|
|
||||||
|
|
||||||
Registers.X0 = (int)SvcResult.Success;
|
Registers.X0 = (int)SvcResult.Success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ namespace Ryujinx
|
||||||
internal Horizon Os { get; private set; }
|
internal Horizon Os { get; private set; }
|
||||||
internal VirtualFs VFs { get; private set; }
|
internal VirtualFs VFs { get; private set; }
|
||||||
|
|
||||||
|
public event EventHandler Finish;
|
||||||
|
|
||||||
public Switch(IGalRenderer Renderer)
|
public Switch(IGalRenderer Renderer)
|
||||||
{
|
{
|
||||||
Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize);
|
Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize);
|
||||||
|
@ -24,15 +26,14 @@ namespace Ryujinx
|
||||||
VFs = new VirtualFs();
|
VFs = new VirtualFs();
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler Finish;
|
|
||||||
internal virtual void OnFinish(EventArgs e)
|
internal virtual void OnFinish(EventArgs e)
|
||||||
{
|
{
|
||||||
EventHandler Handler = Finish;
|
if (Finish != null)
|
||||||
if (Handler != null)
|
|
||||||
{
|
{
|
||||||
Handler(this, e);
|
Finish(this, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
|
|
|
@ -50,7 +50,8 @@ namespace Ryujinx
|
||||||
|
|
||||||
using (GLScreen Screen = new GLScreen(Ns, Renderer))
|
using (GLScreen Screen = new GLScreen(Ns, Renderer))
|
||||||
{
|
{
|
||||||
Ns.Finish += (Sender, Args) => {
|
Ns.Finish += (Sender, Args) =>
|
||||||
|
{
|
||||||
Screen.Exit();
|
Screen.Exit();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Reference in a new issue