Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

Evan Husted 1 год назад
Родитель
Сommit
33f42adb11

+ 1 - 1
src/Ryujinx.HLE/HOS/Horizon.cs

@@ -284,7 +284,7 @@ namespace Ryujinx.HLE.HOS
                 ProcessCreationInfo creationInfo = new("Service", 1, 0, 0x8000000, 1, Flags, 0, 0);
 
                 uint[] defaultCapabilities = {
-                    0x030363F7,
+                    (((uint)KScheduler.CpuCoresCount - 1) << 24) + (((uint)KScheduler.CpuCoresCount - 1) << 16) + 0x63F7u,
                     0x1FFFFFCF,
                     0x207FFFEF,
                     0x47E0060F,

+ 1 - 0
src/Ryujinx.HLE/HOS/Kernel/KernelContext.cs

@@ -63,6 +63,7 @@ namespace Ryujinx.HLE.HOS.Kernel
             TickSource = tickSource;
             Device = device;
             Memory = memory;
+            KScheduler.CpuCoresCount = device.CpuCoresCount;
 
             Running = true;
 

+ 1 - 1
src/Ryujinx.HLE/HOS/Kernel/KernelStatic.cs

@@ -37,7 +37,7 @@ namespace Ryujinx.HLE.HOS.Kernel
                 return result;
             }
 
-            process.DefaultCpuCore = 3;
+            process.DefaultCpuCore = KScheduler.CpuCoresCount - 1;
 
             context.Processes.TryAdd(process.Pid, process);
 

+ 1 - 1
src/Ryujinx.HLE/HOS/Kernel/Process/KProcess.cs

@@ -277,7 +277,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
                 return result;
             }
 
-            result = Capabilities.InitializeForUser(capabilities, MemoryManager);
+            result = Capabilities.InitializeForUser(capabilities, MemoryManager, IsApplication);
 
             if (result != Result.Success)
             {

+ 11 - 6
src/Ryujinx.HLE/HOS/Kernel/Process/KProcessCapabilities.cs

@@ -35,15 +35,15 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
             DebuggingFlags &= ~3u;
             KernelReleaseVersion = KProcess.KernelVersionPacked;
 
-            return Parse(capabilities, memoryManager);
+            return Parse(capabilities, memoryManager, false);
         }
 
-        public Result InitializeForUser(ReadOnlySpan<uint> capabilities, KPageTableBase memoryManager)
+        public Result InitializeForUser(ReadOnlySpan<uint> capabilities, KPageTableBase memoryManager, bool isApplication)
         {
-            return Parse(capabilities, memoryManager);
+            return Parse(capabilities, memoryManager, isApplication);
         }
 
-        private Result Parse(ReadOnlySpan<uint> capabilities, KPageTableBase memoryManager)
+        private Result Parse(ReadOnlySpan<uint> capabilities, KPageTableBase memoryManager, bool isApplication)
         {
             int mask0 = 0;
             int mask1 = 0;
@@ -54,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
 
                 if (cap.GetCapabilityType() != CapabilityType.MapRange)
                 {
-                    Result result = ParseCapability(cap, ref mask0, ref mask1, memoryManager);
+                    Result result = ParseCapability(cap, ref mask0, ref mask1, memoryManager, isApplication);
 
                     if (result != Result.Success)
                     {
@@ -120,7 +120,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
             return Result.Success;
         }
 
-        private Result ParseCapability(uint cap, ref int mask0, ref int mask1, KPageTableBase memoryManager)
+        private Result ParseCapability(uint cap, ref int mask0, ref int mask1, KPageTableBase memoryManager, bool isApplication)
         {
             CapabilityType code = cap.GetCapabilityType();
 
@@ -176,6 +176,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
                         AllowedCpuCoresMask = GetMaskFromMinMax(lowestCpuCore, highestCpuCore);
                         AllowedThreadPriosMask = GetMaskFromMinMax(lowestThreadPrio, highestThreadPrio);
 
+                        if (isApplication && lowestCpuCore == 0 && highestCpuCore != 2)
+                            Ryujinx.Common.Logging.Logger.Error?.Print(Ryujinx.Common.Logging.LogClass.Application, $"Application requested cores with index range {lowestCpuCore} to {highestCpuCore}! Report this to @LotP on the Ryujinx/Ryubing discord server (discord.gg/ryujinx)!");
+                        else if (isApplication)
+                            Ryujinx.Common.Logging.Logger.Info?.Print(Ryujinx.Common.Logging.LogClass.Application, $"Application requested cores with index range {lowestCpuCore} to {highestCpuCore}");
+
                         break;
                     }
 

+ 1 - 1
src/Ryujinx.HLE/HOS/Kernel/SupervisorCall/Syscall.cs

@@ -2683,7 +2683,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
                     return KernelResult.InvalidCombination;
                 }
 
-                if ((uint)preferredCore > 3)
+                if ((uint)preferredCore > KScheduler.CpuCoresCount - 1)
                 {
                     if ((preferredCore | 2) != -1)
                     {

+ 13 - 5
src/Ryujinx.HLE/HOS/Kernel/Threading/KScheduler.cs

@@ -9,13 +9,11 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
     partial class KScheduler : IDisposable
     {
         public const int PrioritiesCount = 64;
-        public const int CpuCoresCount = 4;
+        public static int CpuCoresCount;
 
         private const int RoundRobinTimeQuantumMs = 10;
 
-        private static readonly int[] _preemptionPriorities = { 59, 59, 59, 63 };
-
-        private static readonly int[] _srcCoresHighestPrioThreads = new int[CpuCoresCount];
+        private static int[] _srcCoresHighestPrioThreads;
 
         private readonly KernelContext _context;
         private readonly int _coreId;
@@ -47,6 +45,16 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
             _coreId = coreId;
 
             _currentThread = null;
+
+            if (_srcCoresHighestPrioThreads == null)
+            {
+                _srcCoresHighestPrioThreads = new int[CpuCoresCount];
+            }
+        }
+
+        private static int PreemptionPriorities(int index)
+        {
+            return index == CpuCoresCount - 1 ? 63 : 59;
         }
 
         public static ulong SelectThreads(KernelContext context)
@@ -437,7 +445,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
 
                 for (int core = 0; core < CpuCoresCount; core++)
                 {
-                    RotateScheduledQueue(context, core, _preemptionPriorities[core]);
+                    RotateScheduledQueue(context, core, PreemptionPriorities(core));
                 }
 
                 context.CriticalSection.Leave();

+ 3 - 3
src/Ryujinx.HLE/HOS/Services/ServerBase.cs

@@ -24,14 +24,14 @@ namespace Ryujinx.HLE.HOS.Services
         // not large enough.
         private const int PointerBufferSize = 0x8000;
 
-        private readonly static uint[] _defaultCapabilities = {
-            0x030363F7,
+        private static uint[] _defaultCapabilities => [
+            (((uint)KScheduler.CpuCoresCount - 1) << 24) + (((uint)KScheduler.CpuCoresCount - 1) << 16) + 0x63F7u,
             0x1FFFFFCF,
             0x207FFFEF,
             0x47E0060F,
             0x0048BFFF,
             0x01007FFF,
-        };
+        ];
 
         // The amount of time Dispose() will wait to Join() the thread executing the ServerLoop()
         private static readonly TimeSpan _threadJoinTimeout = TimeSpan.FromSeconds(3);

+ 2 - 0
src/Ryujinx.HLE/Switch.cs

@@ -32,6 +32,8 @@ namespace Ryujinx.HLE
         public TamperMachine TamperMachine { get; }
         public IHostUIHandler UIHandler { get; }
 
+        public int CpuCoresCount = 4; //Switch 1 has 4 cores
+
         public VSyncMode VSyncMode { get; set; } = VSyncMode.Switch;
         public bool CustomVSyncIntervalEnabled { get; set; } = false;
         public int CustomVSyncInterval { get; set; }

+ 1 - 1
src/Ryujinx/Headless/HeadlessRyujinx.Init.cs

@@ -1,4 +1,4 @@
-using DiscordRPC;
+using DiscordRPC;
 using LibHac.Tools.FsSystem;
 using Ryujinx.Audio.Backends.SDL2;
 using Ryujinx.Ava;