diff options
author | gdkchan <gab.dark.100@gmail.com> | 2021-08-11 16:50:33 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-11 21:50:33 +0200 |
commit | bb8a920b63d6d287dba8ec42e298329b933f9654 (patch) | |
tree | ac3f658f3e1b5aaad828d948f8f7cccc68c64000 /Ryujinx.Memory/Tracking/RegionHandle.cs | |
parent | 0f6ec446ea3be41b1c22aa5c3870bd7a6c595d1f (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.cs | 30 |
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) |