From 0b14eb3a61bb8c78802b29075e66fd4c85b03681 Mon Sep 17 00:00:00 2001 From: Mary Date: Mon, 8 May 2023 15:09:02 +0200 Subject: [PATCH] memory: Add Android support --- src/Ryujinx.Memory/MemoryBlock.cs | 2 +- src/Ryujinx.Memory/MemoryManagement.cs | 24 +++++++++---------- src/Ryujinx.Memory/MemoryManagementUnix.cs | 17 +++++++++++++ src/Ryujinx.Memory/MemoryManagerUnixHelper.cs | 9 ++++--- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/Ryujinx.Memory/MemoryBlock.cs b/src/Ryujinx.Memory/MemoryBlock.cs index 7fe7862a9..a715a9376 100644 --- a/src/Ryujinx.Memory/MemoryBlock.cs +++ b/src/Ryujinx.Memory/MemoryBlock.cs @@ -426,7 +426,7 @@ namespace Ryujinx.Memory return OperatingSystem.IsWindowsVersionAtLeast(10, 0, 17134); } - return OperatingSystem.IsLinux() || OperatingSystem.IsMacOS(); + return OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsAndroid(); } return true; diff --git a/src/Ryujinx.Memory/MemoryManagement.cs b/src/Ryujinx.Memory/MemoryManagement.cs index 860d3f368..436a23272 100644 --- a/src/Ryujinx.Memory/MemoryManagement.cs +++ b/src/Ryujinx.Memory/MemoryManagement.cs @@ -10,7 +10,7 @@ namespace Ryujinx.Memory { return MemoryManagementWindows.Allocate((IntPtr)size); } - else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsAndroid()) { return MemoryManagementUnix.Allocate(size, forJit); } @@ -26,7 +26,7 @@ namespace Ryujinx.Memory { return MemoryManagementWindows.Reserve((IntPtr)size, viewCompatible); } - else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsAndroid()) { return MemoryManagementUnix.Reserve(size, forJit); } @@ -42,7 +42,7 @@ namespace Ryujinx.Memory { MemoryManagementWindows.Commit(address, (IntPtr)size); } - else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsAndroid()) { MemoryManagementUnix.Commit(address, size, forJit); } @@ -58,7 +58,7 @@ namespace Ryujinx.Memory { MemoryManagementWindows.Decommit(address, (IntPtr)size); } - else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsAndroid()) { MemoryManagementUnix.Decommit(address, size); } @@ -74,7 +74,7 @@ namespace Ryujinx.Memory { MemoryManagementWindows.MapView(sharedMemory, srcOffset, address, (IntPtr)size, owner); } - else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsAndroid()) { MemoryManagementUnix.MapView(sharedMemory, srcOffset, address, size); } @@ -90,7 +90,7 @@ namespace Ryujinx.Memory { MemoryManagementWindows.UnmapView(sharedMemory, address, (IntPtr)size, owner); } - else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsAndroid()) { MemoryManagementUnix.UnmapView(address, size); } @@ -108,7 +108,7 @@ namespace Ryujinx.Memory { result = MemoryManagementWindows.Reprotect(address, (IntPtr)size, permission, forView); } - else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsAndroid()) { result = MemoryManagementUnix.Reprotect(address, size, permission); } @@ -129,7 +129,7 @@ namespace Ryujinx.Memory { return MemoryManagementWindows.Free(address, (IntPtr)size); } - else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsAndroid()) { return MemoryManagementUnix.Free(address); } @@ -145,7 +145,7 @@ namespace Ryujinx.Memory { return MemoryManagementWindows.CreateSharedMemory((IntPtr)size, reserve); } - else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsAndroid()) { return MemoryManagementUnix.CreateSharedMemory(size, reserve); } @@ -161,7 +161,7 @@ namespace Ryujinx.Memory { MemoryManagementWindows.DestroySharedMemory(handle); } - else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsAndroid()) { MemoryManagementUnix.DestroySharedMemory(handle); } @@ -177,7 +177,7 @@ namespace Ryujinx.Memory { return MemoryManagementWindows.MapSharedMemory(handle); } - else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsAndroid()) { return MemoryManagementUnix.MapSharedMemory(handle, size); } @@ -193,7 +193,7 @@ namespace Ryujinx.Memory { MemoryManagementWindows.UnmapSharedMemory(address); } - else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) + else if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS() || OperatingSystem.IsAndroid()) { MemoryManagementUnix.UnmapSharedMemory(address, size); } diff --git a/src/Ryujinx.Memory/MemoryManagementUnix.cs b/src/Ryujinx.Memory/MemoryManagementUnix.cs index e132dbbb8..fc4508c2c 100644 --- a/src/Ryujinx.Memory/MemoryManagementUnix.cs +++ b/src/Ryujinx.Memory/MemoryManagementUnix.cs @@ -8,6 +8,7 @@ namespace Ryujinx.Memory { [SupportedOSPlatform("linux")] [SupportedOSPlatform("macos")] + [SupportedOSPlatform("android")] static class MemoryManagementUnix { private static readonly ConcurrentDictionary _allocations = new(); @@ -156,6 +157,22 @@ namespace Ryujinx.Memory } } } + else if (OperatingSystem.IsAndroid()) + { + byte[] memName = Encoding.ASCII.GetBytes("Ryujinx-XXXXXX"); + + fixed (byte* pMemName = memName) + { + fd = ASharedMemory_create((IntPtr)pMemName, (nuint)size); + if (fd <= 0) + { + throw new OutOfMemoryException(); + } + } + + // ASharedMemory_create handle ftruncate for us. + return (IntPtr)fd; + } else { byte[] fileName = "/dev/shm/Ryujinx-XXXXXX"u8.ToArray(); diff --git a/src/Ryujinx.Memory/MemoryManagerUnixHelper.cs b/src/Ryujinx.Memory/MemoryManagerUnixHelper.cs index 43888c85b..f9b4f6c4c 100644 --- a/src/Ryujinx.Memory/MemoryManagerUnixHelper.cs +++ b/src/Ryujinx.Memory/MemoryManagerUnixHelper.cs @@ -89,6 +89,9 @@ namespace Ryujinx.Memory [LibraryImport("libc", SetLastError = true)] public static partial int shm_unlink(IntPtr name); + [DllImport("android")] + internal static extern int ASharedMemory_create(IntPtr name, nuint size); + private static int MmapFlagsToSystemFlags(MmapFlags flags) { int result = 0; @@ -110,7 +113,7 @@ namespace Ryujinx.Memory if (flags.HasFlag(MmapFlags.MAP_ANONYMOUS)) { - if (OperatingSystem.IsLinux()) + if (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) { result |= MAP_ANONYMOUS_LINUX_GENERIC; } @@ -126,7 +129,7 @@ namespace Ryujinx.Memory if (flags.HasFlag(MmapFlags.MAP_NORESERVE)) { - if (OperatingSystem.IsLinux()) + if (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) { result |= MAP_NORESERVE_LINUX_GENERIC; } @@ -142,7 +145,7 @@ namespace Ryujinx.Memory if (flags.HasFlag(MmapFlags.MAP_UNLOCKED)) { - if (OperatingSystem.IsLinux()) + if (OperatingSystem.IsLinux() || OperatingSystem.IsAndroid()) { result |= MAP_UNLOCKED_LINUX_GENERIC; }