Initial implementation

This commit is contained in:
LotP1 2025-01-09 01:53:01 +01:00
parent 2226521f6c
commit 644287faa6
8 changed files with 43 additions and 15 deletions

View file

@ -103,6 +103,11 @@ namespace Ryujinx.HLE
/// </summary>
internal readonly bool EnablePtc;
/// <summary>
/// The amount of cpu threads that should be used for emulation.
/// </summary>
internal readonly int CpuCoresCount;
/// <summary>
/// Control if the guest application should be told that there is a Internet connection available.
/// </summary>
@ -208,6 +213,7 @@ namespace Ryujinx.HLE
VSyncMode vSyncMode,
bool enableDockedMode,
bool enablePtc,
int cpuCoresCount,
bool enableInternetAccess,
IntegrityCheckLevel fsIntegrityCheckLevel,
int fsGlobalAccessLogMode,
@ -241,6 +247,7 @@ namespace Ryujinx.HLE
CustomVSyncInterval = customVSyncInterval;
EnableDockedMode = enableDockedMode;
EnablePtc = enablePtc;
CpuCoresCount = cpuCoresCount;
EnableInternetAccess = enableInternetAccess;
FsIntegrityCheckLevel = fsIntegrityCheckLevel;
FsGlobalAccessLogMode = fsGlobalAccessLogMode;

View file

@ -122,7 +122,8 @@ namespace Ryujinx.HLE.HOS
device,
device.Memory,
device.Configuration.MemoryConfiguration.ToKernelMemorySize(),
device.Configuration.MemoryConfiguration.ToKernelMemoryArrange());
device.Configuration.MemoryConfiguration.ToKernelMemoryArrange(),
device.Configuration.CpuCoresCount);
Device = device;

View file

@ -58,11 +58,13 @@ namespace Ryujinx.HLE.HOS.Kernel
Switch device,
MemoryBlock memory,
MemorySize memorySize,
MemoryArrange memoryArrange)
MemoryArrange memoryArrange,
int cpuCoresCount)
{
TickSource = tickSource;
Device = device;
Memory = memory;
KScheduler.CpuCoresCount = cpuCoresCount;
Running = true;

View file

@ -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)
{

View file

@ -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!");
else if (isApplication)
Ryujinx.Common.Logging.Logger.Info?.Print(Ryujinx.Common.Logging.LogClass.Application, $"Application requested cores with index range {lowestCpuCore} to {highestCpuCore}");
break;
}

View file

@ -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();

View file

@ -918,6 +918,7 @@ namespace Ryujinx.Ava
// Initialize Configuration.
var memoryConfiguration = ConfigurationState.Instance.System.DramSize.Value;
int cpuCoresCount = 4; //Switch 1 has 4 cores
Device = new Switch(new HLEConfiguration(
VirtualFileSystem,
@ -934,6 +935,7 @@ namespace Ryujinx.Ava
ConfigurationState.Instance.Graphics.VSyncMode,
ConfigurationState.Instance.System.EnableDockedMode,
ConfigurationState.Instance.System.EnablePtc,
cpuCoresCount,
ConfigurationState.Instance.System.EnableInternetAccess,
ConfigurationState.Instance.System.EnableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
ConfigurationState.Instance.System.FsGlobalAccessLogMode,

View file

@ -1,4 +1,4 @@
using DiscordRPC;
using DiscordRPC;
using LibHac.Tools.FsSystem;
using Ryujinx.Audio.Backends.SDL2;
using Ryujinx.Ava;
@ -329,6 +329,8 @@ namespace Ryujinx.Headless
renderer = new ThreadedRenderer(renderer);
}
int cpuCoresCount = 4; //Switch 1 has 4 cores
HLEConfiguration configuration = new(_virtualFileSystem,
_libHacHorizonManager,
_contentManager,
@ -343,6 +345,7 @@ namespace Ryujinx.Headless
options.VSyncMode,
!options.DisableDockedMode,
!options.DisablePTC,
cpuCoresCount,
options.EnableInternetAccess,
!options.DisableFsIntegrityChecks ? IntegrityCheckLevel.ErrorOnInvalid : IntegrityCheckLevel.None,
options.FsGlobalAccessLogMode,