aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Cpu/MemoryEhMeilleure.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Cpu/MemoryEhMeilleure.cs')
-rw-r--r--Ryujinx.Cpu/MemoryEhMeilleure.cs33
1 files changed, 27 insertions, 6 deletions
diff --git a/Ryujinx.Cpu/MemoryEhMeilleure.cs b/Ryujinx.Cpu/MemoryEhMeilleure.cs
index a8229581..806ef811 100644
--- a/Ryujinx.Cpu/MemoryEhMeilleure.cs
+++ b/Ryujinx.Cpu/MemoryEhMeilleure.cs
@@ -6,36 +6,57 @@ using System.Runtime.InteropServices;
namespace Ryujinx.Cpu
{
- class MemoryEhMeilleure : IDisposable
+ public class MemoryEhMeilleure : IDisposable
{
private delegate bool TrackingEventDelegate(ulong address, ulong size, bool write, bool precise = false);
- private readonly MemoryBlock _addressSpace;
private readonly MemoryTracking _tracking;
private readonly TrackingEventDelegate _trackingEvent;
private readonly ulong _baseAddress;
+ private readonly ulong _mirrorAddress;
- public MemoryEhMeilleure(MemoryBlock addressSpace, MemoryTracking tracking)
+ public MemoryEhMeilleure(MemoryBlock addressSpace, MemoryBlock addressSpaceMirror, MemoryTracking tracking)
{
- _addressSpace = addressSpace;
_tracking = tracking;
- _baseAddress = (ulong)_addressSpace.Pointer;
+ _baseAddress = (ulong)addressSpace.Pointer;
ulong endAddress = _baseAddress + addressSpace.Size;
- _trackingEvent = new TrackingEventDelegate(tracking.VirtualMemoryEventEh);
+ _trackingEvent = new TrackingEventDelegate(tracking.VirtualMemoryEvent);
bool added = NativeSignalHandler.AddTrackedRegion((nuint)_baseAddress, (nuint)endAddress, Marshal.GetFunctionPointerForDelegate(_trackingEvent));
if (!added)
{
throw new InvalidOperationException("Number of allowed tracked regions exceeded.");
}
+
+ if (OperatingSystem.IsWindows())
+ {
+ // Add a tracking event with no signal handler for the mirror on Windows.
+ // The native handler has its own code to check for the partial overlap race when regions are protected by accident,
+ // and when there is no signal handler present.
+
+ _mirrorAddress = (ulong)addressSpaceMirror.Pointer;
+ ulong endAddressMirror = _mirrorAddress + addressSpace.Size;
+
+ bool addedMirror = NativeSignalHandler.AddTrackedRegion((nuint)_mirrorAddress, (nuint)endAddressMirror, IntPtr.Zero);
+
+ if (!addedMirror)
+ {
+ throw new InvalidOperationException("Number of allowed tracked regions exceeded.");
+ }
+ }
}
public void Dispose()
{
NativeSignalHandler.RemoveTrackedRegion((nuint)_baseAddress);
+
+ if (_mirrorAddress != 0)
+ {
+ NativeSignalHandler.RemoveTrackedRegion((nuint)_mirrorAddress);
+ }
}
}
}