diff options
Diffstat (limited to 'Ryujinx.Memory/Tracking')
| -rw-r--r-- | Ryujinx.Memory/Tracking/IRegionHandle.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.Memory/Tracking/RegionHandle.cs | 30 |
2 files changed, 29 insertions, 3 deletions
diff --git a/Ryujinx.Memory/Tracking/IRegionHandle.cs b/Ryujinx.Memory/Tracking/IRegionHandle.cs index 33628da6..cd33e5c8 100644 --- a/Ryujinx.Memory/Tracking/IRegionHandle.cs +++ b/Ryujinx.Memory/Tracking/IRegionHandle.cs @@ -10,7 +10,7 @@ namespace Ryujinx.Memory.Tracking ulong Size { get; } ulong EndAddress { get; } - void Reprotect(); + void Reprotect(bool asDirty = false); void RegisterAction(RegionSignal action); } } diff --git a/Ryujinx.Memory/Tracking/RegionHandle.cs b/Ryujinx.Memory/Tracking/RegionHandle.cs index 3ddcb6db..4da184dd 100644 --- a/Ryujinx.Memory/Tracking/RegionHandle.cs +++ b/Ryujinx.Memory/Tracking/RegionHandle.cs @@ -1,4 +1,5 @@ using Ryujinx.Memory.Range; +using System; using System.Collections.Generic; using System.Threading; @@ -19,9 +20,12 @@ namespace Ryujinx.Memory.Tracking internal IMultiRegionHandle Parent { get; set; } internal int SequenceNumber { get; set; } + private event Action _onDirty; + private RegionSignal _preAction; // Action to perform before a read or write. This will block the memory access. private readonly List<VirtualRegion> _regions; private readonly MemoryTracking _tracking; + private bool _disposed; internal MemoryPermission RequiredPermission => _preAction != null ? MemoryPermission.None : (Dirty ? MemoryPermission.ReadAndWrite : MemoryPermission.Read); internal RegionSignal PreAction => _preAction; @@ -60,7 +64,12 @@ namespace Ryujinx.Memory.Tracking if (write) { + bool oldDirty = Dirty; Dirty = true; + if (!oldDirty) + { + _onDirty?.Invoke(); + } Parent?.SignalWrite(); } } @@ -68,9 +77,9 @@ namespace Ryujinx.Memory.Tracking /// <summary> /// Consume the dirty flag for this handle, and reprotect so it can be set on the next write. /// </summary> - public void Reprotect() + public void Reprotect(bool asDirty = false) { - Dirty = false; + Dirty = asDirty; lock (_tracking.TrackingLock) { foreach (VirtualRegion region in _regions) @@ -101,6 +110,16 @@ namespace Ryujinx.Memory.Tracking } /// <summary> + /// Register an action to perform when the region is written to. + /// This action will not be removed when it is called - it is called each time the dirty flag is set. + /// </summary> + /// <param name="action">Action to call on dirty</param> + public void RegisterDirtyEvent(Action action) + { + _onDirty += action; + } + + /// <summary> /// Add a child virtual region to this handle. /// </summary> /// <param name="region">Virtual region to add as a child</param> @@ -125,6 +144,13 @@ namespace Ryujinx.Memory.Tracking /// </summary> public void Dispose() { + if (_disposed) + { + throw new ObjectDisposedException(GetType().FullName); + } + + _disposed = true; + lock (_tracking.TrackingLock) { foreach (VirtualRegion region in _regions) |
