aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Memory
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Memory')
-rw-r--r--Ryujinx.Memory/Range/RangeList.cs46
-rw-r--r--Ryujinx.Memory/Tracking/MultiRegionHandle.cs11
-rw-r--r--Ryujinx.Memory/Tracking/RegionHandle.cs1
-rw-r--r--Ryujinx.Memory/Tracking/SmartMultiRegionHandle.cs20
-rw-r--r--Ryujinx.Memory/Tracking/VirtualRegion.cs4
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>