From ebddc40550f9107c7b52f8709a12ef070244f8f0 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Sat, 17 Feb 2018 18:36:08 -0300 Subject: [PATCH] Add events to shared memory, make it work better with direct memory --- Ryujinx/OsHle/Handles/HSharedMem.cs | 69 +++++++++++++++++++++++++++-- Ryujinx/OsHle/Horizon.cs | 42 +++++++++++++----- Ryujinx/OsHle/Process.cs | 4 +- Ryujinx/OsHle/Svc/SvcHandler.cs | 1 + Ryujinx/OsHle/Svc/SvcMemory.cs | 19 ++++---- Ryujinx/Switch.cs | 9 ++-- Ryujinx/Ui/Program.cs | 3 +- 7 files changed, 116 insertions(+), 31 deletions(-) diff --git a/Ryujinx/OsHle/Handles/HSharedMem.cs b/Ryujinx/OsHle/Handles/HSharedMem.cs index 2030ff0a..a493276a 100644 --- a/Ryujinx/OsHle/Handles/HSharedMem.cs +++ b/Ryujinx/OsHle/Handles/HSharedMem.cs @@ -1,13 +1,76 @@ +using System; +using System.Collections.Generic; + namespace Ryujinx.OsHle.Handles { class HSharedMem { - public long PhysPos { get; private set; } - public long VirtPos { get; set; } + private List Positions; + + public int PositionsCount => Positions.Count; + + public EventHandler MemoryMapped; + public EventHandler MemoryUnmapped; public HSharedMem(long PhysPos) { - this.PhysPos = PhysPos; + Positions = new List(); + } + + 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; + } } } } \ No newline at end of file diff --git a/Ryujinx/OsHle/Horizon.cs b/Ryujinx/OsHle/Horizon.cs index 01380105..815495eb 100644 --- a/Ryujinx/OsHle/Horizon.cs +++ b/Ryujinx/OsHle/Horizon.cs @@ -31,6 +31,8 @@ namespace Ryujinx.OsHle private ConcurrentDictionary Processes; + private HSharedMem HidSharedMem; + private AMemoryAlloc Allocator; private Switch Ns; @@ -56,7 +58,12 @@ namespace Ryujinx.OsHle HidOffset = Allocator.Alloc(HidSize); 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)); } @@ -105,7 +112,7 @@ namespace Ryujinx.OsHle Processes.TryAdd(ProcessId, MainProcess); } - public void LoadProgram(string FileName) + public void LoadProgram(string FileName) { int ProcessId = IdGen.GenerateId(); @@ -139,18 +146,23 @@ namespace Ryujinx.OsHle } } - internal bool ExitProcess(int ProcessId) { - Process process; - var Success = Processes.TryRemove(ProcessId, out process); - if (Success) { - process.StopAllThreads(); + internal bool ExitProcess(int ProcessId) + { + bool Success = Processes.TryRemove(ProcessId, out Process Process); + + if (Success) + { + Process.StopAllThreads(); } - if (Processes.Count == 0) { + if (Processes.Count == 0) + { Ns.OnFinish(EventArgs.Empty); } + return Success; } + internal bool TryGetProcess(int ProcessId, out Process Process) { if (!Processes.TryGetValue(ProcessId, out Process)) @@ -176,11 +188,21 @@ namespace Ryujinx.OsHle 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() { - HSharedMem HidSharedMem = Handles.GetData(HidHandle); + HidSharedMem.TryGetLastVirtualPosition(out long Position); - return HidSharedMem.VirtPos; + return Position; } } } \ No newline at end of file diff --git a/Ryujinx/OsHle/Process.cs b/Ryujinx/OsHle/Process.cs index d1f020b5..bb27024f 100644 --- a/Ryujinx/OsHle/Process.cs +++ b/Ryujinx/OsHle/Process.cs @@ -118,7 +118,7 @@ namespace Ryujinx.OsHle { if (MainThread != null) { - if (MainThread.Thread.IsAlive) + while (MainThread.Thread.IsAlive) { MainThread.Thread.StopExecution(); } @@ -126,7 +126,7 @@ namespace Ryujinx.OsHle foreach (AThread Thread in TlsSlots.Values) { - if (Thread.IsAlive) + while (Thread.IsAlive) { Thread.StopExecution(); } diff --git a/Ryujinx/OsHle/Svc/SvcHandler.cs b/Ryujinx/OsHle/Svc/SvcHandler.cs index 2191793a..eaf41057 100644 --- a/Ryujinx/OsHle/Svc/SvcHandler.cs +++ b/Ryujinx/OsHle/Svc/SvcHandler.cs @@ -8,6 +8,7 @@ namespace Ryujinx.OsHle.Svc partial class SvcHandler { private delegate void SvcFunc(ARegisters Registers); + private Dictionary SvcFuncs; private Switch Ns; diff --git a/Ryujinx/OsHle/Svc/SvcMemory.cs b/Ryujinx/OsHle/Svc/SvcMemory.cs index f6cef4cc..4711072d 100644 --- a/Ryujinx/OsHle/Svc/SvcMemory.cs +++ b/Ryujinx/OsHle/Svc/SvcMemory.cs @@ -65,21 +65,18 @@ namespace Ryujinx.OsHle.Svc private void SvcMapSharedMemory(ARegisters Registers) { - int Handle = (int)Registers.X0; - long Position = (long)Registers.X1; - long Size = (long)Registers.X2; - int Perm = (int)Registers.X3; + int Handle = (int)Registers.X0; + long Src = (long)Registers.X1; + long Size = (long)Registers.X2; + int Perm = (int)Registers.X3; - HSharedMem HndData = Ns.Os.Handles.GetData(Handle); + HSharedMem SharedMem = Ns.Os.Handles.GetData(Handle); - if (HndData != null) + if (SharedMem != null) { - long Src = Position; - long Dst = HndData.PhysPos; + SharedMem.AddVirtualPosition(Src); - HndData.VirtPos = Src; - - Memory.Manager.MapPhys(Position, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm); + Memory.Manager.MapPhys(Src, Size, (int)MemoryType.SharedMemory, (AMemoryPerm)Perm); Registers.X0 = (int)SvcResult.Success; } diff --git a/Ryujinx/Switch.cs b/Ryujinx/Switch.cs index e912da86..0e83a37c 100644 --- a/Ryujinx/Switch.cs +++ b/Ryujinx/Switch.cs @@ -15,6 +15,8 @@ namespace Ryujinx internal Horizon Os { get; private set; } internal VirtualFs VFs { get; private set; } + public event EventHandler Finish; + public Switch(IGalRenderer Renderer) { Ram = Marshal.AllocHGlobal((IntPtr)AMemoryMgr.RamSize); @@ -24,15 +26,14 @@ namespace Ryujinx VFs = new VirtualFs(); } - public event EventHandler Finish; internal virtual void OnFinish(EventArgs e) { - EventHandler Handler = Finish; - if (Handler != null) + if (Finish != null) { - Handler(this, e); + Finish(this, e); } } + public void Dispose() { Dispose(true); diff --git a/Ryujinx/Ui/Program.cs b/Ryujinx/Ui/Program.cs index 88a8a117..2f29411a 100644 --- a/Ryujinx/Ui/Program.cs +++ b/Ryujinx/Ui/Program.cs @@ -50,7 +50,8 @@ namespace Ryujinx using (GLScreen Screen = new GLScreen(Ns, Renderer)) { - Ns.Finish += (Sender, Args) => { + Ns.Finish += (Sender, Args) => + { Screen.Exit(); };