Просмотр исходного кода

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

gdkchan 8 лет назад
Родитель
Сommit
ebddc40550

+ 66 - 3
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<long> Positions;
+
+        public int PositionsCount => Positions.Count;
+
+        public EventHandler<EventArgs> MemoryMapped;
+        public EventHandler<EventArgs> MemoryUnmapped;
 
         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;
+            }
         }
     }
 }

+ 32 - 10
Ryujinx/OsHle/Horizon.cs

@@ -31,6 +31,8 @@ namespace Ryujinx.OsHle
 
         private ConcurrentDictionary<int, Process> 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<HSharedMem>(HidHandle);
+            HidSharedMem.TryGetLastVirtualPosition(out long Position);
 
-            return HidSharedMem.VirtPos;
+            return Position;
         }
     }
 }

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

+ 1 - 0
Ryujinx/OsHle/Svc/SvcHandler.cs

@@ -8,6 +8,7 @@ namespace Ryujinx.OsHle.Svc
     partial class SvcHandler
     {
         private delegate void SvcFunc(ARegisters Registers);
+
         private Dictionary<int, SvcFunc> SvcFuncs;
 
         private Switch  Ns;

+ 8 - 11
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<HSharedMem>(Handle);
+            HSharedMem SharedMem = Ns.Os.Handles.GetData<HSharedMem>(Handle);
 
-            if (HndData != null)
+            if (SharedMem != null)
             {
-                long Src = Position;
-                long Dst = HndData.PhysPos;
-
-                HndData.VirtPos = Src;
+                SharedMem.AddVirtualPosition(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;
             }

+ 5 - 4
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);

+ 2 - 1
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();
                 };