Add events to shared memory, make it work better with direct memory

This commit is contained in:
gdkchan 2018-02-17 18:36:08 -03:00
parent 161193e113
commit ebddc40550
7 changed files with 116 additions and 31 deletions

View file

@ -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;
}
} }
} }
} }

View file

@ -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;
} }
} }
} }

View file

@ -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();
} }

View file

@ -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;

View file

@ -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;
} }

View file

@ -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);

View file

@ -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();
}; };