diff options
Diffstat (limited to 'Ryujinx.Memory/Tracking')
| -rw-r--r-- | Ryujinx.Memory/Tracking/MemoryTracking.cs | 28 | ||||
| -rw-r--r-- | Ryujinx.Memory/Tracking/RegionHandle.cs | 24 | ||||
| -rw-r--r-- | Ryujinx.Memory/Tracking/VirtualRegion.cs | 6 |
3 files changed, 41 insertions, 17 deletions
diff --git a/Ryujinx.Memory/Tracking/MemoryTracking.cs b/Ryujinx.Memory/Tracking/MemoryTracking.cs index aafb418d..ed3d7e38 100644 --- a/Ryujinx.Memory/Tracking/MemoryTracking.cs +++ b/Ryujinx.Memory/Tracking/MemoryTracking.cs @@ -1,4 +1,6 @@ -using Ryujinx.Memory.Range; +using Ryujinx.Common.Pools; +using Ryujinx.Memory.Range; +using System; using System.Collections.Generic; namespace Ryujinx.Memory.Tracking @@ -14,9 +16,6 @@ namespace Ryujinx.Memory.Tracking // Only use these from within the lock. private readonly NonOverlappingRangeList<VirtualRegion> _virtualRegions; - // Only use these from within the lock. - private readonly VirtualRegion[] _virtualResults = new VirtualRegion[10]; - private readonly int _pageSize; /// <summary> @@ -62,12 +61,13 @@ namespace Ryujinx.Memory.Tracking lock (TrackingLock) { - var results = _virtualResults; - int count = _virtualRegions.FindOverlapsNonOverlapping(va, size, ref results); + ref var overlaps = ref ThreadStaticArray<VirtualRegion>.Get(); + + int count = _virtualRegions.FindOverlapsNonOverlapping(va, size, ref overlaps); for (int i = 0; i < count; i++) { - VirtualRegion region = results[i]; + VirtualRegion region = overlaps[i]; // If the region has been fully remapped, signal that it has been mapped again. bool remapped = _memoryManager.IsRangeMapped(region.Address, region.Size); @@ -94,12 +94,13 @@ namespace Ryujinx.Memory.Tracking lock (TrackingLock) { - var results = _virtualResults; - int count = _virtualRegions.FindOverlapsNonOverlapping(va, size, ref results); + ref var overlaps = ref ThreadStaticArray<VirtualRegion>.Get(); + + int count = _virtualRegions.FindOverlapsNonOverlapping(va, size, ref overlaps); for (int i = 0; i < count; i++) { - VirtualRegion region = results[i]; + VirtualRegion region = overlaps[i]; region.SignalMappingChanged(false); } @@ -201,8 +202,9 @@ namespace Ryujinx.Memory.Tracking lock (TrackingLock) { - var results = _virtualResults; - int count = _virtualRegions.FindOverlapsNonOverlapping(address, size, ref results); + ref var overlaps = ref ThreadStaticArray<VirtualRegion>.Get(); + + int count = _virtualRegions.FindOverlapsNonOverlapping(address, size, ref overlaps); if (count == 0) { @@ -221,7 +223,7 @@ namespace Ryujinx.Memory.Tracking for (int i = 0; i < count; i++) { - VirtualRegion region = results[i]; + VirtualRegion region = overlaps[i]; region.Signal(address, size, write); } } diff --git a/Ryujinx.Memory/Tracking/RegionHandle.cs b/Ryujinx.Memory/Tracking/RegionHandle.cs index 2e45ef80..2df02f1e 100644 --- a/Ryujinx.Memory/Tracking/RegionHandle.cs +++ b/Ryujinx.Memory/Tracking/RegionHandle.cs @@ -1,6 +1,7 @@ using Ryujinx.Memory.Range; using System; using System.Collections.Generic; +using System.Linq; using System.Threading; namespace Ryujinx.Memory.Tracking @@ -112,7 +113,7 @@ namespace Ryujinx.Memory.Tracking /// Signal that a memory action occurred within this handle's virtual regions. /// </summary> /// <param name="write">Whether the region was written to or read</param> - internal void Signal(ulong address, ulong size, bool write) + internal void Signal(ulong address, ulong size, bool write, ref IList<RegionHandle> handleIterable) { RegionSignal action = Interlocked.Exchange(ref _preAction, null); @@ -124,7 +125,26 @@ namespace Ryujinx.Memory.Tracking return; } - action?.Invoke(address, size); + if (action != null) + { + // Copy the handles list in case it changes when we're out of the lock. + if (handleIterable is List<RegionHandle>) + { + handleIterable = handleIterable.ToArray(); + } + + // Temporarily release the tracking lock while we're running the action. + Monitor.Exit(_tracking.TrackingLock); + + try + { + action.Invoke(address, size); + } + finally + { + Monitor.Enter(_tracking.TrackingLock); + } + } if (write) { diff --git a/Ryujinx.Memory/Tracking/VirtualRegion.cs b/Ryujinx.Memory/Tracking/VirtualRegion.cs index e758f38e..40f56351 100644 --- a/Ryujinx.Memory/Tracking/VirtualRegion.cs +++ b/Ryujinx.Memory/Tracking/VirtualRegion.cs @@ -21,9 +21,11 @@ namespace Ryujinx.Memory.Tracking public override void Signal(ulong address, ulong size, bool write) { - foreach (var handle in Handles) + IList<RegionHandle> handles = Handles; + + for (int i = 0; i < handles.Count; i++) { - handle.Signal(address, size, write); + handles[i].Signal(address, size, write, ref handles); } UpdateProtection(); |
