diff options
Diffstat (limited to 'Ryujinx.Memory')
| -rw-r--r-- | Ryujinx.Memory/Range/RangeList.cs | 46 | ||||
| -rw-r--r-- | Ryujinx.Memory/Tracking/MultiRegionHandle.cs | 11 | ||||
| -rw-r--r-- | Ryujinx.Memory/Tracking/RegionHandle.cs | 1 | ||||
| -rw-r--r-- | Ryujinx.Memory/Tracking/SmartMultiRegionHandle.cs | 20 | ||||
| -rw-r--r-- | Ryujinx.Memory/Tracking/VirtualRegion.cs | 4 |
5 files changed, 57 insertions, 25 deletions
diff --git a/Ryujinx.Memory/Range/RangeList.cs b/Ryujinx.Memory/Range/RangeList.cs index 3c8c4c4c..fd260656 100644 --- a/Ryujinx.Memory/Range/RangeList.cs +++ b/Ryujinx.Memory/Range/RangeList.cs @@ -12,16 +12,16 @@ namespace Ryujinx.Memory.Range { private const int ArrayGrowthSize = 32; - private readonly List<T> _items; + protected readonly List<T> Items; - public int Count => _items.Count; + public int Count => Items.Count; /// <summary> /// Creates a new range list. /// </summary> public RangeList() { - _items = new List<T>(); + Items = new List<T>(); } /// <summary> @@ -37,7 +37,7 @@ namespace Ryujinx.Memory.Range index = ~index; } - _items.Insert(index, item); + Items.Insert(index, item); } /// <summary> @@ -51,21 +51,21 @@ namespace Ryujinx.Memory.Range if (index >= 0) { - while (index > 0 && _items[index - 1].Address == item.Address) + while (index > 0 && Items[index - 1].Address == item.Address) { index--; } - while (index < _items.Count) + while (index < Items.Count) { - if (_items[index].Equals(item)) + if (Items[index].Equals(item)) { - _items.RemoveAt(index); + Items.RemoveAt(index); return true; } - if (_items[index].Address > item.Address) + if (Items[index].Address > item.Address) { break; } @@ -110,7 +110,7 @@ namespace Ryujinx.Memory.Range return default(T); } - return _items[index]; + return Items[index]; } /// <summary> @@ -137,7 +137,7 @@ namespace Ryujinx.Memory.Range ulong endAddress = address + size; - foreach (T item in _items) + foreach (T item in Items) { if (item.Address >= endAddress) { @@ -196,7 +196,7 @@ namespace Ryujinx.Memory.Range if (index >= 0) { - while (index > 0 && _items[index - 1].OverlapsWith(address, size)) + while (index > 0 && Items[index - 1].OverlapsWith(address, size)) { index--; } @@ -208,9 +208,9 @@ namespace Ryujinx.Memory.Range Array.Resize(ref output, outputIndex + ArrayGrowthSize); } - output[outputIndex++] = _items[index++]; + output[outputIndex++] = Items[index++]; } - while (index < _items.Count && _items[index].OverlapsWith(address, size)); + while (index < Items.Count && Items[index].OverlapsWith(address, size)); } return outputIndex; @@ -230,14 +230,14 @@ namespace Ryujinx.Memory.Range if (index >= 0) { - while (index > 0 && _items[index - 1].Address == address) + while (index > 0 && Items[index - 1].Address == address) { index--; } - while (index < _items.Count) + while (index < Items.Count) { - T overlap = _items[index++]; + T overlap = Items[index++]; if (overlap.Address != address) { @@ -264,7 +264,7 @@ namespace Ryujinx.Memory.Range private int BinarySearch(ulong address) { int left = 0; - int right = _items.Count - 1; + int right = Items.Count - 1; while (left <= right) { @@ -272,7 +272,7 @@ namespace Ryujinx.Memory.Range int middle = left + (range >> 1); - T item = _items[middle]; + T item = Items[middle]; if (item.Address == address) { @@ -301,7 +301,7 @@ namespace Ryujinx.Memory.Range private int BinarySearch(ulong address, ulong size) { int left = 0; - int right = _items.Count - 1; + int right = Items.Count - 1; while (left <= right) { @@ -309,7 +309,7 @@ namespace Ryujinx.Memory.Range int middle = left + (range >> 1); - T item = _items[middle]; + T item = Items[middle]; if (item.OverlapsWith(address, size)) { @@ -331,12 +331,12 @@ namespace Ryujinx.Memory.Range public IEnumerator<T> GetEnumerator() { - return _items.GetEnumerator(); + return Items.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { - return _items.GetEnumerator(); + return Items.GetEnumerator(); } } }
\ No newline at end of file diff --git a/Ryujinx.Memory/Tracking/MultiRegionHandle.cs b/Ryujinx.Memory/Tracking/MultiRegionHandle.cs index 02ae3a8b..df154bc2 100644 --- a/Ryujinx.Memory/Tracking/MultiRegionHandle.cs +++ b/Ryujinx.Memory/Tracking/MultiRegionHandle.cs @@ -123,6 +123,17 @@ namespace Ryujinx.Memory.Tracking } } + public void RegisterAction(ulong address, ulong size, RegionSignal action) + { + int startHandle = (int)((address - Address) / Granularity); + int lastHandle = (int)((address + (size - 1) - Address) / Granularity); + + for (int i = startHandle; i <= lastHandle; i++) + { + _handles[i].RegisterAction(action); + } + } + public void Dispose() { foreach (var handle in _handles) diff --git a/Ryujinx.Memory/Tracking/RegionHandle.cs b/Ryujinx.Memory/Tracking/RegionHandle.cs index 96898c21..3ddcb6db 100644 --- a/Ryujinx.Memory/Tracking/RegionHandle.cs +++ b/Ryujinx.Memory/Tracking/RegionHandle.cs @@ -24,6 +24,7 @@ namespace Ryujinx.Memory.Tracking private readonly MemoryTracking _tracking; internal MemoryPermission RequiredPermission => _preAction != null ? MemoryPermission.None : (Dirty ? MemoryPermission.ReadAndWrite : MemoryPermission.Read); + internal RegionSignal PreAction => _preAction; /// <summary> /// Create a new region handle. The handle is registered with the given tracking object, diff --git a/Ryujinx.Memory/Tracking/SmartMultiRegionHandle.cs b/Ryujinx.Memory/Tracking/SmartMultiRegionHandle.cs index 60188400..8bc10c41 100644 --- a/Ryujinx.Memory/Tracking/SmartMultiRegionHandle.cs +++ b/Ryujinx.Memory/Tracking/SmartMultiRegionHandle.cs @@ -41,6 +41,17 @@ namespace Ryujinx.Memory.Tracking Dirty = true; } + public void RegisterAction(RegionSignal action) + { + foreach (var handle in _handles) + { + if (handle != null) + { + handle?.RegisterAction((address, size) => action(handle.Address, handle.Size)); + } + } + } + public void QueryModified(Action<ulong, ulong> modifiedAction) { if (!Dirty) @@ -66,14 +77,23 @@ namespace Ryujinx.Memory.Tracking ulong size = HandlesToBytes(splitIndex - handleIndex); // First, the target handle must be removed. Its data can still be used to determine the new handles. + RegionSignal signal = handle.PreAction; handle.Dispose(); RegionHandle splitLow = _tracking.BeginTracking(address, size); splitLow.Parent = this; + if (signal != null) + { + splitLow.RegisterAction(signal); + } _handles[handleIndex] = splitLow; RegionHandle splitHigh = _tracking.BeginTracking(address + size, handle.Size - size); splitHigh.Parent = this; + if (signal != null) + { + splitHigh.RegisterAction(signal); + } _handles[splitIndex] = splitHigh; } diff --git a/Ryujinx.Memory/Tracking/VirtualRegion.cs b/Ryujinx.Memory/Tracking/VirtualRegion.cs index 90fb55d6..15a11568 100644 --- a/Ryujinx.Memory/Tracking/VirtualRegion.cs +++ b/Ryujinx.Memory/Tracking/VirtualRegion.cs @@ -22,12 +22,12 @@ namespace Ryujinx.Memory.Tracking public override void Signal(ulong address, ulong size, bool write) { - _tracking.ProtectVirtualRegion(this, MemoryPermission.ReadAndWrite); // Remove our protection immedately. - foreach (var handle in Handles) { handle.Signal(address, size, write); } + + UpdateProtection(); } /// <summary> |
