forked from Mirror/Ryujinx
[Ryujinx.Memory] Address dotnet-format issues (#5386)
* dotnet format style --severity info Some changes were manually reverted. * dotnet format analyzers --serverity info Some changes have been minimally adapted. * Silence dotnet format IDE0059 warnings * Address or silence dotnet format IDE1006 warnings * Address dotnet format CA1816 warnings * Address or silence dotnet format CA1069 warnings * Address remaining dotnet format analyzer warnings * Address review comments * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Format if-blocks correctly * Another rebase, another dotnet format run * Run dotnet format after rebase and remove unused usings - analyzers - style - whitespace * Add comments to disabled warnings * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * Address review feedback * Assign Decommit to ReplacePlaceholder * Run final dotnet format pass * Organize imports again * Add trailing commas * Add missing newline
This commit is contained in:
parent
46b7c905f5
commit
0a75b73fa4
25 changed files with 98 additions and 66 deletions
|
@ -136,7 +136,7 @@ namespace Ryujinx.Memory
|
||||||
{
|
{
|
||||||
size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
|
size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
|
||||||
|
|
||||||
data.Slice(0, size).CopyTo(GetHostSpanContiguous(va, size));
|
data[..size].CopyTo(GetHostSpanContiguous(va, size));
|
||||||
|
|
||||||
offset += size;
|
offset += size;
|
||||||
}
|
}
|
||||||
|
@ -215,7 +215,7 @@ namespace Ryujinx.Memory
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private int GetPagesCount(ulong va, uint size, out ulong startVa)
|
private static int GetPagesCount(ulong va, uint size, out ulong startVa)
|
||||||
{
|
{
|
||||||
// WARNING: Always check if ulong does not overflow during the operations.
|
// WARNING: Always check if ulong does not overflow during the operations.
|
||||||
startVa = va & ~(ulong)PageMask;
|
startVa = va & ~(ulong)PageMask;
|
||||||
|
@ -224,7 +224,7 @@ namespace Ryujinx.Memory
|
||||||
return (int)(vaSpan / PageSize);
|
return (int)(vaSpan / PageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThrowMemoryNotContiguous() => throw new MemoryNotContiguousException();
|
private static void ThrowMemoryNotContiguous() => throw new MemoryNotContiguousException();
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private bool IsContiguousAndMapped(ulong va, int size) => IsContiguous(va, size) && IsMapped(va);
|
private bool IsContiguousAndMapped(ulong va, int size) => IsContiguous(va, size) && IsMapped(va);
|
||||||
|
@ -361,7 +361,7 @@ namespace Ryujinx.Memory
|
||||||
{
|
{
|
||||||
size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
|
size = Math.Min(data.Length, PageSize - (int)(va & PageMask));
|
||||||
|
|
||||||
GetHostSpanContiguous(va, size).CopyTo(data.Slice(0, size));
|
GetHostSpanContiguous(va, size).CopyTo(data[..size]);
|
||||||
|
|
||||||
offset += size;
|
offset += size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,6 @@ namespace Ryujinx.Memory
|
||||||
/// Indicates that the memory will be used to store JIT generated code.
|
/// Indicates that the memory will be used to store JIT generated code.
|
||||||
/// On some platforms, this requires special flags to be passed that will allow the memory to be executable.
|
/// On some platforms, this requires special flags to be passed that will allow the memory to be executable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Jit = 1 << 5
|
Jit = 1 << 5,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -364,9 +364,9 @@ namespace Ryujinx.Memory
|
||||||
/// <param name="pointer">Native pointer</param>
|
/// <param name="pointer">Native pointer</param>
|
||||||
/// <param name="offset">Offset to add</param>
|
/// <param name="offset">Offset to add</param>
|
||||||
/// <returns>Native pointer with the added offset</returns>
|
/// <returns>Native pointer with the added offset</returns>
|
||||||
private IntPtr PtrAddr(IntPtr pointer, ulong offset)
|
private static IntPtr PtrAddr(IntPtr pointer, ulong offset)
|
||||||
{
|
{
|
||||||
return (IntPtr)(pointer.ToInt64() + (long)offset);
|
return new IntPtr(pointer.ToInt64() + (long)offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace Ryujinx.Memory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IntPtr ptr = mmap(IntPtr.Zero, size, prot, flags, -1, 0);
|
IntPtr ptr = Mmap(IntPtr.Zero, size, prot, flags, -1, 0);
|
||||||
|
|
||||||
if (ptr == MAP_FAILED)
|
if (ptr == MAP_FAILED)
|
||||||
{
|
{
|
||||||
|
@ -115,7 +115,7 @@ namespace Ryujinx.Memory
|
||||||
MemoryPermission.ReadAndExecute => MmapProts.PROT_READ | MmapProts.PROT_EXEC,
|
MemoryPermission.ReadAndExecute => MmapProts.PROT_READ | MmapProts.PROT_EXEC,
|
||||||
MemoryPermission.ReadWriteExecute => MmapProts.PROT_READ | MmapProts.PROT_WRITE | MmapProts.PROT_EXEC,
|
MemoryPermission.ReadWriteExecute => MmapProts.PROT_READ | MmapProts.PROT_WRITE | MmapProts.PROT_EXEC,
|
||||||
MemoryPermission.Execute => MmapProts.PROT_EXEC,
|
MemoryPermission.Execute => MmapProts.PROT_EXEC,
|
||||||
_ => throw new MemoryProtectionException(permission)
|
_ => throw new MemoryProtectionException(permission),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,12 +185,12 @@ namespace Ryujinx.Memory
|
||||||
|
|
||||||
public static void DestroySharedMemory(IntPtr handle)
|
public static void DestroySharedMemory(IntPtr handle)
|
||||||
{
|
{
|
||||||
close((int)handle);
|
close(handle.ToInt32());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IntPtr MapSharedMemory(IntPtr handle, ulong size)
|
public static IntPtr MapSharedMemory(IntPtr handle, ulong size)
|
||||||
{
|
{
|
||||||
return mmap(IntPtr.Zero, size, MmapProts.PROT_READ | MmapProts.PROT_WRITE, MmapFlags.MAP_SHARED, (int)handle, 0);
|
return Mmap(IntPtr.Zero, size, MmapProts.PROT_READ | MmapProts.PROT_WRITE, MmapFlags.MAP_SHARED, handle.ToInt32(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UnmapSharedMemory(IntPtr address, ulong size)
|
public static void UnmapSharedMemory(IntPtr address, ulong size)
|
||||||
|
@ -200,12 +200,12 @@ namespace Ryujinx.Memory
|
||||||
|
|
||||||
public static void MapView(IntPtr sharedMemory, ulong srcOffset, IntPtr location, ulong size)
|
public static void MapView(IntPtr sharedMemory, ulong srcOffset, IntPtr location, ulong size)
|
||||||
{
|
{
|
||||||
mmap(location, size, MmapProts.PROT_READ | MmapProts.PROT_WRITE, MmapFlags.MAP_FIXED | MmapFlags.MAP_SHARED, (int)sharedMemory, (long)srcOffset);
|
Mmap(location, size, MmapProts.PROT_READ | MmapProts.PROT_WRITE, MmapFlags.MAP_FIXED | MmapFlags.MAP_SHARED, sharedMemory.ToInt32(), (long)srcOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UnmapView(IntPtr location, ulong size)
|
public static void UnmapView(IntPtr location, ulong size)
|
||||||
{
|
{
|
||||||
mmap(location, size, MmapProts.PROT_NONE, MmapFlags.MAP_FIXED | MmapFlags.MAP_PRIVATE | MmapFlags.MAP_ANONYMOUS | MmapFlags.MAP_NORESERVE, -1, 0);
|
Mmap(location, size, MmapProts.PROT_NONE, MmapFlags.MAP_FIXED | MmapFlags.MAP_PRIVATE | MmapFlags.MAP_ANONYMOUS | MmapFlags.MAP_NORESERVE, -1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@ namespace Ryujinx.Memory
|
||||||
PROT_NONE = 0,
|
PROT_NONE = 0,
|
||||||
PROT_READ = 1,
|
PROT_READ = 1,
|
||||||
PROT_WRITE = 2,
|
PROT_WRITE = 2,
|
||||||
PROT_EXEC = 4
|
PROT_EXEC = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
|
@ -26,7 +26,7 @@ namespace Ryujinx.Memory
|
||||||
MAP_NORESERVE = 8,
|
MAP_NORESERVE = 8,
|
||||||
MAP_FIXED = 16,
|
MAP_FIXED = 16,
|
||||||
MAP_UNLOCKED = 32,
|
MAP_UNLOCKED = 32,
|
||||||
MAP_JIT_DARWIN = 0x800
|
MAP_JIT_DARWIN = 0x800,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
|
@ -164,7 +164,7 @@ namespace Ryujinx.Memory
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IntPtr mmap(IntPtr address, ulong length, MmapProts prot, MmapFlags flags, int fd, long offset)
|
public static IntPtr Mmap(IntPtr address, ulong length, MmapProts prot, MmapFlags flags, int fd, long offset)
|
||||||
{
|
{
|
||||||
return Internal_mmap(address, length, prot, MmapFlagsToSystemFlags(flags), fd, offset);
|
return Internal_mmap(address, length, prot, MmapFlagsToSystemFlags(flags), fd, offset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,6 @@ namespace Ryujinx.Memory
|
||||||
/// and allocate its own private storage for the mapping.
|
/// and allocate its own private storage for the mapping.
|
||||||
/// This allows some mappings that would otherwise fail due to host platform restrictions to succeed.
|
/// This allows some mappings that would otherwise fail due to host platform restrictions to succeed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Private = 1 << 0
|
Private = 1 << 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,6 @@ namespace Ryujinx.Memory
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Indicates an invalid protection.
|
/// Indicates an invalid protection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Invalid = 255
|
Invalid = 255,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,12 +5,12 @@ namespace Ryujinx.Memory.Range
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Range of memory composed of an address and size.
|
/// Range of memory composed of an address and size.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public struct HostMemoryRange : IEquatable<HostMemoryRange>
|
public readonly struct HostMemoryRange : IEquatable<HostMemoryRange>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An empty memory range, with a null address and zero size.
|
/// An empty memory range, with a null address and zero size.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static HostMemoryRange Empty => new HostMemoryRange(0, 0);
|
public static HostMemoryRange Empty => new(0, 0);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start address of the range.
|
/// Start address of the range.
|
||||||
|
@ -67,5 +67,15 @@ namespace Ryujinx.Memory.Range
|
||||||
{
|
{
|
||||||
return HashCode.Combine(Address, Size);
|
return HashCode.Combine(Address, Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(HostMemoryRange left, HostMemoryRange right)
|
||||||
|
{
|
||||||
|
return left.Equals(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(HostMemoryRange left, HostMemoryRange right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An empty memory range, with a null address and zero size.
|
/// An empty memory range, with a null address and zero size.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static MemoryRange Empty => new MemoryRange(0UL, 0);
|
public static MemoryRange Empty => new(0UL, 0);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start address of the range.
|
/// Start address of the range.
|
||||||
|
|
|
@ -310,7 +310,7 @@ namespace Ryujinx.Memory.Range
|
||||||
return _singleRange.GetHashCode();
|
return _singleRange.GetHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
HashCode hash = new HashCode();
|
HashCode hash = new();
|
||||||
|
|
||||||
foreach (MemoryRange range in _ranges)
|
foreach (MemoryRange range in _ranges)
|
||||||
{
|
{
|
||||||
|
@ -328,5 +328,15 @@ namespace Ryujinx.Memory.Range
|
||||||
{
|
{
|
||||||
return HasSingleRange ? _singleRange.ToString() : string.Join(", ", _ranges);
|
return HasSingleRange ? _singleRange.ToString() : string.Join(", ", _ranges);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(MultiRange left, MultiRange right)
|
||||||
|
{
|
||||||
|
return left.Equals(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(MultiRange left, MultiRange right)
|
||||||
|
{
|
||||||
|
return !(left == right);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,7 +238,7 @@ namespace Ryujinx.Memory.Range
|
||||||
|
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
{
|
{
|
||||||
return default(T);
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _items[index].Value;
|
return _items[index].Value;
|
||||||
|
@ -398,7 +398,7 @@ namespace Ryujinx.Memory.Range
|
||||||
/// <returns>List index of the item, or complement index of nearest item with lower value on the list</returns>
|
/// <returns>List index of the item, or complement index of nearest item with lower value on the list</returns>
|
||||||
private int BinarySearch(ulong address)
|
private int BinarySearch(ulong address)
|
||||||
{
|
{
|
||||||
int left = 0;
|
int left = 0;
|
||||||
int right = Count - 1;
|
int right = Count - 1;
|
||||||
|
|
||||||
while (left <= right)
|
while (left <= right)
|
||||||
|
@ -435,7 +435,7 @@ namespace Ryujinx.Memory.Range
|
||||||
/// <returns>List index of the item, or complement index of nearest item with lower value on the list</returns>
|
/// <returns>List index of the item, or complement index of nearest item with lower value on the list</returns>
|
||||||
private int BinarySearch(ulong address, ulong endAddress)
|
private int BinarySearch(ulong address, ulong endAddress)
|
||||||
{
|
{
|
||||||
int left = 0;
|
int left = 0;
|
||||||
int right = Count - 1;
|
int right = Count - 1;
|
||||||
|
|
||||||
while (left <= right)
|
while (left <= right)
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace Ryujinx.Memory.Tracking
|
||||||
/// This lock must be obtained when traversing or updating the region-handle hierarchy.
|
/// This lock must be obtained when traversing or updating the region-handle hierarchy.
|
||||||
/// It is not required when reading dirty flags.
|
/// It is not required when reading dirty flags.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal object TrackingLock = new object();
|
internal object TrackingLock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new tracking structure for the given "physical" memory block,
|
/// Create a new tracking structure for the given "physical" memory block,
|
||||||
|
@ -114,7 +114,7 @@ namespace Ryujinx.Memory.Tracking
|
||||||
/// <returns>A list of virtual regions within the given range</returns>
|
/// <returns>A list of virtual regions within the given range</returns>
|
||||||
internal List<VirtualRegion> GetVirtualRegionsForHandle(ulong va, ulong size)
|
internal List<VirtualRegion> GetVirtualRegionsForHandle(ulong va, ulong size)
|
||||||
{
|
{
|
||||||
List<VirtualRegion> result = new List<VirtualRegion>();
|
List<VirtualRegion> result = new();
|
||||||
_virtualRegions.GetOrAddRegions(result, va, size, (va, size) => new VirtualRegion(this, va, size));
|
_virtualRegions.GetOrAddRegions(result, va, size, (va, size) => new VirtualRegion(this, va, size));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -172,7 +172,7 @@ namespace Ryujinx.Memory.Tracking
|
||||||
lock (TrackingLock)
|
lock (TrackingLock)
|
||||||
{
|
{
|
||||||
bool mapped = _memoryManager.IsRangeMapped(address, size);
|
bool mapped = _memoryManager.IsRangeMapped(address, size);
|
||||||
RegionHandle handle = new RegionHandle(this, paAddress, paSize, address, size, id, mapped);
|
RegionHandle handle = new(this, paAddress, paSize, address, size, id, mapped);
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,7 @@ namespace Ryujinx.Memory.Tracking
|
||||||
lock (TrackingLock)
|
lock (TrackingLock)
|
||||||
{
|
{
|
||||||
bool mapped = _memoryManager.IsRangeMapped(address, size);
|
bool mapped = _memoryManager.IsRangeMapped(address, size);
|
||||||
RegionHandle handle = new RegionHandle(this, paAddress, paSize, address, size, bitmap, bit, id, mapped);
|
RegionHandle handle = new(this, paAddress, paSize, address, size, bitmap, bit, id, mapped);
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -21,11 +22,11 @@ namespace Ryujinx.Memory.Tracking
|
||||||
private readonly ulong Granularity;
|
private readonly ulong Granularity;
|
||||||
private readonly ulong Size;
|
private readonly ulong Size;
|
||||||
|
|
||||||
private ConcurrentBitmap _dirtyBitmap;
|
private readonly ConcurrentBitmap _dirtyBitmap;
|
||||||
|
|
||||||
private int _sequenceNumber;
|
private int _sequenceNumber;
|
||||||
private BitMap _sequenceNumberBitmap;
|
private readonly BitMap _sequenceNumberBitmap;
|
||||||
private BitMap _dirtyCheckedBitmap;
|
private readonly BitMap _dirtyCheckedBitmap;
|
||||||
private int _uncheckedHandles;
|
private int _uncheckedHandles;
|
||||||
|
|
||||||
public bool Dirty { get; private set; } = true;
|
public bool Dirty { get; private set; } = true;
|
||||||
|
@ -54,7 +55,7 @@ namespace Ryujinx.Memory.Tracking
|
||||||
// It is assumed that the provided handles do not overlap, in order, are on page boundaries,
|
// It is assumed that the provided handles do not overlap, in order, are on page boundaries,
|
||||||
// and don't extend past the requested range.
|
// and don't extend past the requested range.
|
||||||
|
|
||||||
foreach (RegionHandle handle in handles)
|
foreach (RegionHandle handle in handles.Cast<RegionHandle>())
|
||||||
{
|
{
|
||||||
int startIndex = (int)((handle.RealAddress - address) / granularity);
|
int startIndex = (int)((handle.RealAddress - address) / granularity);
|
||||||
|
|
||||||
|
@ -406,6 +407,8 @@ namespace Ryujinx.Memory.Tracking
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
|
||||||
foreach (var handle in _handles)
|
foreach (var handle in _handles)
|
||||||
{
|
{
|
||||||
handle.Dispose();
|
handle.Dispose();
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Memory.Tracking
|
namespace Ryujinx.Memory.Tracking
|
||||||
|
@ -50,7 +49,7 @@ namespace Ryujinx.Memory.Tracking
|
||||||
|
|
||||||
internal IMultiRegionHandle Parent { get; set; }
|
internal IMultiRegionHandle Parent { get; set; }
|
||||||
|
|
||||||
private event Action _onDirty;
|
private event Action OnDirty;
|
||||||
|
|
||||||
private readonly object _preActionLock = new();
|
private readonly object _preActionLock = new();
|
||||||
private RegionSignal _preAction; // Action to perform before a read or write. This will block the memory access.
|
private RegionSignal _preAction; // Action to perform before a read or write. This will block the memory access.
|
||||||
|
@ -269,7 +268,7 @@ namespace Ryujinx.Memory.Tracking
|
||||||
Dirty = true;
|
Dirty = true;
|
||||||
if (!oldDirty)
|
if (!oldDirty)
|
||||||
{
|
{
|
||||||
_onDirty?.Invoke();
|
OnDirty?.Invoke();
|
||||||
}
|
}
|
||||||
Parent?.SignalWrite();
|
Parent?.SignalWrite();
|
||||||
}
|
}
|
||||||
|
@ -311,7 +310,10 @@ namespace Ryujinx.Memory.Tracking
|
||||||
/// <param name="consecutiveCheck">True if this reprotect is the result of consecutive dirty checks</param>
|
/// <param name="consecutiveCheck">True if this reprotect is the result of consecutive dirty checks</param>
|
||||||
public void Reprotect(bool asDirty, bool consecutiveCheck = false)
|
public void Reprotect(bool asDirty, bool consecutiveCheck = false)
|
||||||
{
|
{
|
||||||
if (_volatile) return;
|
if (_volatile)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Dirty = asDirty;
|
Dirty = asDirty;
|
||||||
|
|
||||||
|
@ -403,7 +405,7 @@ namespace Ryujinx.Memory.Tracking
|
||||||
/// <param name="action">Action to call on dirty</param>
|
/// <param name="action">Action to call on dirty</param>
|
||||||
public void RegisterDirtyEvent(Action action)
|
public void RegisterDirtyEvent(Action action)
|
||||||
{
|
{
|
||||||
_onDirty += action;
|
OnDirty += action;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -461,6 +463,8 @@ namespace Ryujinx.Memory.Tracking
|
||||||
{
|
{
|
||||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
|
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
|
|
||||||
lock (_tracking.TrackingLock)
|
lock (_tracking.TrackingLock)
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Ryujinx.Memory.Tracking
|
||||||
private readonly ulong _address;
|
private readonly ulong _address;
|
||||||
private readonly ulong _granularity;
|
private readonly ulong _granularity;
|
||||||
private readonly ulong _size;
|
private readonly ulong _size;
|
||||||
private MemoryTracking _tracking;
|
private readonly MemoryTracking _tracking;
|
||||||
private readonly int _id;
|
private readonly int _id;
|
||||||
|
|
||||||
public bool Dirty { get; private set; } = true;
|
public bool Dirty { get; private set; } = true;
|
||||||
|
@ -271,6 +271,8 @@ namespace Ryujinx.Memory.Tracking
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
|
||||||
foreach (var handle in _handles)
|
foreach (var handle in _handles)
|
||||||
{
|
{
|
||||||
handle?.Dispose();
|
handle?.Dispose();
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Ryujinx.Memory.Tracking
|
||||||
/// </summary>
|
/// </summary>
|
||||||
class VirtualRegion : AbstractRegion
|
class VirtualRegion : AbstractRegion
|
||||||
{
|
{
|
||||||
public List<RegionHandle> Handles = new List<RegionHandle>();
|
public List<RegionHandle> Handles = new();
|
||||||
|
|
||||||
private readonly MemoryTracking _tracking;
|
private readonly MemoryTracking _tracking;
|
||||||
private MemoryPermission _lastPermission;
|
private MemoryPermission _lastPermission;
|
||||||
|
@ -86,7 +86,10 @@ namespace Ryujinx.Memory.Tracking
|
||||||
foreach (var handle in Handles)
|
foreach (var handle in Handles)
|
||||||
{
|
{
|
||||||
result &= handle.RequiredPermission;
|
result &= handle.RequiredPermission;
|
||||||
if (result == 0) return result;
|
if (result == 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +131,7 @@ namespace Ryujinx.Memory.Tracking
|
||||||
|
|
||||||
public override INonOverlappingRange Split(ulong splitAddress)
|
public override INonOverlappingRange Split(ulong splitAddress)
|
||||||
{
|
{
|
||||||
VirtualRegion newRegion = new VirtualRegion(_tracking, splitAddress, EndAddress - splitAddress, _lastPermission);
|
VirtualRegion newRegion = new(_tracking, splitAddress, EndAddress - splitAddress, _lastPermission);
|
||||||
Size = splitAddress - Address;
|
Size = splitAddress - Address;
|
||||||
|
|
||||||
// The new region inherits all of our parents.
|
// The new region inherits all of our parents.
|
||||||
|
|
|
@ -31,9 +31,11 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
|
|
||||||
_partialUnmapStatePtr = PartialUnmapState.GlobalState;
|
_partialUnmapStatePtr = PartialUnmapState.GlobalState;
|
||||||
|
|
||||||
_partialUnmapTrimThread = new Thread(TrimThreadLocalMapLoop);
|
_partialUnmapTrimThread = new Thread(TrimThreadLocalMapLoop)
|
||||||
_partialUnmapTrimThread.Name = "CPU.PartialUnmapTrimThread";
|
{
|
||||||
_partialUnmapTrimThread.IsBackground = true;
|
Name = "CPU.PartialUnmapTrimThread",
|
||||||
|
IsBackground = true,
|
||||||
|
};
|
||||||
_partialUnmapTrimThread.Start();
|
_partialUnmapTrimThread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,8 +706,6 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
count = _protections.GetNodes(address, endAddress, ref overlaps);
|
count = _protections.GetNodes(address, endAddress, ref overlaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong startAddress = address;
|
|
||||||
|
|
||||||
for (int index = 0; index < count; index++)
|
for (int index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
var protection = overlaps[index];
|
var protection = overlaps[index];
|
||||||
|
|
|
@ -7,8 +7,8 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
[SupportedOSPlatform("windows")]
|
[SupportedOSPlatform("windows")]
|
||||||
static partial class WindowsApi
|
static partial class WindowsApi
|
||||||
{
|
{
|
||||||
public static readonly IntPtr InvalidHandleValue = new IntPtr(-1);
|
public static readonly IntPtr InvalidHandleValue = new(-1);
|
||||||
public static readonly IntPtr CurrentProcessHandle = new IntPtr(-1);
|
public static readonly IntPtr CurrentProcessHandle = new(-1);
|
||||||
|
|
||||||
[LibraryImport("kernel32.dll", SetLastError = true)]
|
[LibraryImport("kernel32.dll", SetLastError = true)]
|
||||||
public static partial IntPtr VirtualAlloc(
|
public static partial IntPtr VirtualAlloc(
|
||||||
|
@ -96,7 +96,7 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
MemoryPermission.ReadAndExecute => MemoryProtection.ExecuteRead,
|
MemoryPermission.ReadAndExecute => MemoryProtection.ExecuteRead,
|
||||||
MemoryPermission.ReadWriteExecute => MemoryProtection.ExecuteReadWrite,
|
MemoryPermission.ReadWriteExecute => MemoryProtection.ExecuteReadWrite,
|
||||||
MemoryPermission.Execute => MemoryProtection.Execute,
|
MemoryPermission.Execute => MemoryProtection.Execute,
|
||||||
_ => throw new MemoryProtectionException(permission)
|
_ => throw new MemoryProtectionException(permission),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,14 +10,14 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
Commit = 0x1000,
|
Commit = 0x1000,
|
||||||
Reserve = 0x2000,
|
Reserve = 0x2000,
|
||||||
Decommit = 0x4000,
|
Decommit = 0x4000,
|
||||||
ReplacePlaceholder = 0x4000,
|
ReplacePlaceholder = Decommit,
|
||||||
Release = 0x8000,
|
Release = 0x8000,
|
||||||
ReservePlaceholder = 0x40000,
|
ReservePlaceholder = 0x40000,
|
||||||
Reset = 0x80000,
|
Reset = 0x80000,
|
||||||
Physical = 0x400000,
|
Physical = 0x400000,
|
||||||
TopDown = 0x100000,
|
TopDown = 0x100000,
|
||||||
WriteWatch = 0x200000,
|
WriteWatch = 0x200000,
|
||||||
LargePages = 0x20000000
|
LargePages = 0x20000000,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
|
@ -33,7 +33,7 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
ExecuteWriteCopy = 0x80,
|
ExecuteWriteCopy = 0x80,
|
||||||
GuardModifierflag = 0x100,
|
GuardModifierflag = 0x100,
|
||||||
NoCacheModifierflag = 0x200,
|
NoCacheModifierflag = 0x200,
|
||||||
WriteCombineModifierflag = 0x400
|
WriteCombineModifierflag = 0x400,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
|
@ -47,6 +47,6 @@ namespace Ryujinx.Memory.WindowsShared
|
||||||
SectionCommit = 0x8000000,
|
SectionCommit = 0x8000000,
|
||||||
SectionImage = 0x1000000,
|
SectionImage = 0x1000000,
|
||||||
SectionNoCache = 0x10000000,
|
SectionNoCache = 0x10000000,
|
||||||
SectionReserve = 0x4000000
|
SectionReserve = 0x4000000,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue