MemoryEhMeilleure.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. using ARMeilleure.Signal;
  2. using Ryujinx.Memory;
  3. using Ryujinx.Memory.Tracking;
  4. using System;
  5. using System.Runtime.InteropServices;
  6. namespace Ryujinx.Cpu
  7. {
  8. public class MemoryEhMeilleure : IDisposable
  9. {
  10. private delegate bool TrackingEventDelegate(ulong address, ulong size, bool write, bool precise = false);
  11. private readonly MemoryTracking _tracking;
  12. private readonly TrackingEventDelegate _trackingEvent;
  13. private readonly ulong _baseAddress;
  14. private readonly ulong _mirrorAddress;
  15. public MemoryEhMeilleure(MemoryBlock addressSpace, MemoryBlock addressSpaceMirror, MemoryTracking tracking)
  16. {
  17. _tracking = tracking;
  18. _baseAddress = (ulong)addressSpace.Pointer;
  19. ulong endAddress = _baseAddress + addressSpace.Size;
  20. _trackingEvent = new TrackingEventDelegate(tracking.VirtualMemoryEvent);
  21. bool added = NativeSignalHandler.AddTrackedRegion((nuint)_baseAddress, (nuint)endAddress, Marshal.GetFunctionPointerForDelegate(_trackingEvent));
  22. if (!added)
  23. {
  24. throw new InvalidOperationException("Number of allowed tracked regions exceeded.");
  25. }
  26. if (OperatingSystem.IsWindows())
  27. {
  28. // Add a tracking event with no signal handler for the mirror on Windows.
  29. // The native handler has its own code to check for the partial overlap race when regions are protected by accident,
  30. // and when there is no signal handler present.
  31. _mirrorAddress = (ulong)addressSpaceMirror.Pointer;
  32. ulong endAddressMirror = _mirrorAddress + addressSpace.Size;
  33. bool addedMirror = NativeSignalHandler.AddTrackedRegion((nuint)_mirrorAddress, (nuint)endAddressMirror, IntPtr.Zero);
  34. if (!addedMirror)
  35. {
  36. throw new InvalidOperationException("Number of allowed tracked regions exceeded.");
  37. }
  38. }
  39. }
  40. public void Dispose()
  41. {
  42. NativeSignalHandler.RemoveTrackedRegion((nuint)_baseAddress);
  43. if (_mirrorAddress != 0)
  44. {
  45. NativeSignalHandler.RemoveTrackedRegion((nuint)_mirrorAddress);
  46. }
  47. }
  48. }
  49. }