diff --git a/src/Ryujinx.Common/PlatformInfo.cs b/src/Ryujinx.Common/PlatformInfo.cs new file mode 100644 index 000000000..b77351e0e --- /dev/null +++ b/src/Ryujinx.Common/PlatformInfo.cs @@ -0,0 +1,7 @@ +namespace Ryujinx.Common +{ + public static class PlatformInfo + { + public static bool IsBionic { get; set; } + } +} diff --git a/src/Ryujinx.Memory/MemoryBlock.cs b/src/Ryujinx.Memory/MemoryBlock.cs index 59ee269bb..56023b6f6 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() || Common.PlatformInfo.IsBionic; } return true; diff --git a/src/Ryujinx.Memory/MemoryManagement.cs b/src/Ryujinx.Memory/MemoryManagement.cs index 860d3f368..f57308e09 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() || Common.PlatformInfo.IsBionic) { 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() || Common.PlatformInfo.IsBionic) { 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() || Common.PlatformInfo.IsBionic) { 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() || Common.PlatformInfo.IsBionic) { 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() || Common.PlatformInfo.IsBionic) { 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() || Common.PlatformInfo.IsBionic) { 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() || Common.PlatformInfo.IsBionic) { 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() || Common.PlatformInfo.IsBionic) { 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() || Common.PlatformInfo.IsBionic) { 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() || Common.PlatformInfo.IsBionic) { 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() || Common.PlatformInfo.IsBionic) { 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() || Common.PlatformInfo.IsBionic) { MemoryManagementUnix.UnmapSharedMemory(address, size); } diff --git a/src/Ryujinx.Memory/MemoryManagementUnix.cs b/src/Ryujinx.Memory/MemoryManagementUnix.cs index e132dbbb8..82e9b2613 100644 --- a/src/Ryujinx.Memory/MemoryManagementUnix.cs +++ b/src/Ryujinx.Memory/MemoryManagementUnix.cs @@ -1,3 +1,4 @@ +using Ryujinx.Common.Logging; using System; using System.Collections.Concurrent; using System.Runtime.InteropServices; @@ -8,6 +9,7 @@ namespace Ryujinx.Memory { [SupportedOSPlatform("linux")] [SupportedOSPlatform("macos")] + [SupportedOSPlatform("android")] static class MemoryManagementUnix { private static readonly ConcurrentDictionary _allocations = new(); @@ -156,6 +158,24 @@ namespace Ryujinx.Memory } } } + else if (Ryujinx.Common.PlatformInfo.IsBionic) + { + byte[] memName = "Ryujinx-XXXXXX"u8.ToArray(); + + Logger.Debug?.Print(LogClass.Cpu, $"Creating Android SharedMemory of size:{size}"); + + 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..8bed0d2db 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() || Common.PlatformInfo.IsBionic) { result |= MAP_ANONYMOUS_LINUX_GENERIC; } @@ -126,7 +129,7 @@ namespace Ryujinx.Memory if (flags.HasFlag(MmapFlags.MAP_NORESERVE)) { - if (OperatingSystem.IsLinux()) + if (OperatingSystem.IsLinux() || Common.PlatformInfo.IsBionic) { result |= MAP_NORESERVE_LINUX_GENERIC; } @@ -142,7 +145,7 @@ namespace Ryujinx.Memory if (flags.HasFlag(MmapFlags.MAP_UNLOCKED)) { - if (OperatingSystem.IsLinux()) + if (OperatingSystem.IsLinux() || Common.PlatformInfo.IsBionic) { result |= MAP_UNLOCKED_LINUX_GENERIC; }