diff --git a/Ryujinx.Memory/MemoryManagement.cs b/Ryujinx.Memory/MemoryManagement.cs index fa21f9d31..5dbfcc332 100644 --- a/Ryujinx.Memory/MemoryManagement.cs +++ b/Ryujinx.Memory/MemoryManagement.cs @@ -12,8 +12,7 @@ namespace Ryujinx.Memory return MemoryManagementWindows.Allocate(sizeNint); } - else if (OperatingSystem.IsLinux() || - OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) { return MemoryManagementUnix.Allocate(size); } @@ -31,8 +30,7 @@ namespace Ryujinx.Memory return MemoryManagementWindows.Reserve(sizeNint, viewCompatible); } - else if (OperatingSystem.IsLinux() || - OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) { return MemoryManagementUnix.Reserve(size); } @@ -50,8 +48,7 @@ namespace Ryujinx.Memory return MemoryManagementWindows.Commit(address, sizeNint); } - else if (OperatingSystem.IsLinux() || - OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) { return MemoryManagementUnix.Commit(address, size); } @@ -69,8 +66,7 @@ namespace Ryujinx.Memory return MemoryManagementWindows.Decommit(address, sizeNint); } - else if (OperatingSystem.IsLinux() || - OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) { return MemoryManagementUnix.Decommit(address, size); } @@ -88,6 +84,10 @@ namespace Ryujinx.Memory MemoryManagementWindows.MapView(sharedMemory, srcOffset, address, sizeNint); } + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + { + MemoryManagementUnix.Remap(address, (IntPtr)((ulong)sharedMemory + srcOffset), size); + } else { throw new PlatformNotSupportedException(); @@ -102,6 +102,10 @@ namespace Ryujinx.Memory MemoryManagementWindows.UnmapView(address, sizeNint); } + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + { + MemoryManagementUnix.Unmap(address, size); + } else { throw new PlatformNotSupportedException(); @@ -118,8 +122,7 @@ namespace Ryujinx.Memory result = MemoryManagementWindows.Reprotect(address, sizeNint, permission, forView); } - else if (OperatingSystem.IsLinux() || - OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) { result = MemoryManagementUnix.Reprotect(address, size, permission); } @@ -140,8 +143,7 @@ namespace Ryujinx.Memory { return MemoryManagementWindows.Free(address); } - else if (OperatingSystem.IsLinux() || - OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) { return MemoryManagementUnix.Free(address); } @@ -159,8 +161,7 @@ namespace Ryujinx.Memory return MemoryManagementWindows.CreateSharedMemory(sizeNint, reserve); } - else if (OperatingSystem.IsLinux() || - OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) { return MemoryManagementUnix.CreateSharedMemory(size, reserve); } @@ -176,8 +177,7 @@ namespace Ryujinx.Memory { MemoryManagementWindows.DestroySharedMemory(handle); } - else if (OperatingSystem.IsLinux() || - OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) { MemoryManagementUnix.DestroySharedMemory(handle); } @@ -193,8 +193,7 @@ namespace Ryujinx.Memory { return MemoryManagementWindows.MapSharedMemory(handle); } - else if (OperatingSystem.IsLinux() || - OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) { return MemoryManagementUnix.MapSharedMemory(handle); } @@ -210,8 +209,7 @@ namespace Ryujinx.Memory { MemoryManagementWindows.UnmapSharedMemory(address); } - else if (OperatingSystem.IsLinux() || - OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) { MemoryManagementUnix.UnmapSharedMemory(address); } @@ -223,8 +221,7 @@ namespace Ryujinx.Memory public static IntPtr Remap(IntPtr target, IntPtr source, ulong size) { - if (OperatingSystem.IsLinux() || - OperatingSystem.IsMacOS()) + if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) { return MemoryManagementUnix.Remap(target, source, size); } diff --git a/Ryujinx.Memory/MemoryManagementUnix.cs b/Ryujinx.Memory/MemoryManagementUnix.cs index 9e3ec48af..08b69ea78 100644 --- a/Ryujinx.Memory/MemoryManagementUnix.cs +++ b/Ryujinx.Memory/MemoryManagementUnix.cs @@ -136,6 +136,11 @@ namespace Ryujinx.Memory return false; } + public static bool Unmap(IntPtr address, ulong size) + { + return munmap(address, size) == 0; + } + public static IntPtr Remap(IntPtr target, IntPtr source, ulong size) { int flags = 1; diff --git a/Ryujinx.Memory/Range/HostMemoryRange.cs b/Ryujinx.Memory/Range/HostMemoryRange.cs new file mode 100644 index 000000000..c6d8689c5 --- /dev/null +++ b/Ryujinx.Memory/Range/HostMemoryRange.cs @@ -0,0 +1,71 @@ +using System; + +namespace Ryujinx.Memory.Range +{ + /// + /// Range of memory composed of an address and size. + /// + public struct HostMemoryRange : IEquatable + { + /// + /// An empty memory range, with a null address and zero size. + /// + public static HostMemoryRange Empty => new HostMemoryRange(0, 0); + + /// + /// Start address of the range. + /// + public nuint Address { get; } + + /// + /// Size of the range in bytes. + /// + public ulong Size { get; } + + /// + /// Address where the range ends (exclusive). + /// + public nuint EndAddress => Address + (nuint)Size; + + /// + /// Creates a new memory range with the specified address and size. + /// + /// Start address + /// Size in bytes + public HostMemoryRange(nuint address, ulong size) + { + Address = address; + Size = size; + } + + /// + /// Checks if the range overlaps with another. + /// + /// The other range to check for overlap + /// True if the ranges overlap, false otherwise + public bool OverlapsWith(HostMemoryRange other) + { + nuint thisAddress = Address; + nuint thisEndAddress = EndAddress; + nuint otherAddress = other.Address; + nuint otherEndAddress = other.EndAddress; + + return thisAddress < otherEndAddress && otherAddress < thisEndAddress; + } + + public override bool Equals(object obj) + { + return obj is HostMemoryRange other && Equals(other); + } + + public bool Equals(HostMemoryRange other) + { + return Address == other.Address && Size == other.Size; + } + + public override int GetHashCode() + { + return HashCode.Combine(Address, Size); + } + } +}