aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Memory/Tracking/RegionHandle.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2021-08-11 16:50:33 -0300
committerGitHub <noreply@github.com>2021-08-11 21:50:33 +0200
commitbb8a920b63d6d287dba8ec42e298329b933f9654 (patch)
treeac3f658f3e1b5aaad828d948f8f7cccc68c64000 /Ryujinx.Memory/Tracking/RegionHandle.cs
parent0f6ec446ea3be41b1c22aa5c3870bd7a6c595d1f (diff)
Do not dirty memory tracking region handles if they are partially unmapped (#2536)
Diffstat (limited to 'Ryujinx.Memory/Tracking/RegionHandle.cs')
-rw-r--r--Ryujinx.Memory/Tracking/RegionHandle.cs30
1 files changed, 29 insertions, 1 deletions
diff --git a/Ryujinx.Memory/Tracking/RegionHandle.cs b/Ryujinx.Memory/Tracking/RegionHandle.cs
index 69d77977..2e45ef80 100644
--- a/Ryujinx.Memory/Tracking/RegionHandle.cs
+++ b/Ryujinx.Memory/Tracking/RegionHandle.cs
@@ -43,7 +43,26 @@ namespace Ryujinx.Memory.Tracking
private int _volatileCount = 0;
private bool _volatile;
- internal MemoryPermission RequiredPermission => _preAction != null ? MemoryPermission.None : (Dirty ? MemoryPermission.ReadAndWrite : MemoryPermission.Read);
+ internal MemoryPermission RequiredPermission
+ {
+ get
+ {
+ // If this is unmapped, allow reprotecting as RW as it can't be dirtied.
+ // This is required for the partial unmap cases where part of the data are still being accessed.
+ if (Unmapped)
+ {
+ return MemoryPermission.ReadAndWrite;
+ }
+
+ if (_preAction != null)
+ {
+ return MemoryPermission.None;
+ }
+
+ return Dirty ? MemoryPermission.ReadAndWrite : MemoryPermission.Read;
+ }
+ }
+
internal RegionSignal PreAction => _preAction;
/// <summary>
@@ -96,6 +115,15 @@ namespace Ryujinx.Memory.Tracking
internal void Signal(ulong address, ulong size, bool write)
{
RegionSignal action = Interlocked.Exchange(ref _preAction, null);
+
+ // If this handle was already unmapped (even if just partially),
+ // then we have nothing to do until it is mapped again.
+ // The pre-action should be still consumed to avoid flushing on remap.
+ if (Unmapped)
+ {
+ return;
+ }
+
action?.Invoke(address, size);
if (write)