Use winapi to get physical core count and revert back to WMI as fall back for CPU name

This commit is contained in:
sunshineinabox 2023-08-01 11:03:52 -07:00
parent a15eb00ca7
commit e59da65d54
7 changed files with 97 additions and 58 deletions

View file

@ -46,8 +46,8 @@
<PackageVersion Include="System.Drawing.Common" Version="7.0.0" />
<PackageVersion Include="System.IdentityModel.Tokens.Jwt" Version="6.31.0" />
<PackageVersion Include="System.IO.Hashing" Version="7.0.0" />
<PackageVersion Include="System.Management" Version="7.0.2" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
<PackageVersion Include="WmiLight" Version="4.0.0" />
<PackageVersion Include="XamlNameReferenceGenerator" Version="1.6.1" />
</ItemGroup>
</Project>

View file

@ -20,7 +20,6 @@
<PublishSingleFile>true</PublishSingleFile>
<TrimmerSingleWarn>false</TrimmerSingleWarn>
<PublishTrimmed>true</PublishTrimmed>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<TrimMode>partial</TrimMode>
</PropertyGroup>

View file

@ -9,7 +9,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" />
<PackageReference Include="MsgPack.Cli" />
<PackageReference Include="WmiLight" />
<PackageReference Include="System.Management" />
</ItemGroup>
</Project>

View file

@ -6,7 +6,6 @@ using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.X86;
using System.Text;
using WmiLight;
namespace Ryujinx.Common.SystemInfo
{
@ -128,7 +127,7 @@ namespace Ryujinx.Common.SystemInfo
}
catch (Exception ex)
{
Logger.Error?.Print(LogClass.Application,$"An error occurred while trying to get the physical core count: {ex.Message}");
Logger.Error?.Print(LogClass.Application, $"An error occurred while trying to get the physical core count: {ex.Message}");
}
_cachedPhysicalCoreCount = coreCount;

View file

@ -1,10 +1,8 @@
using System;
using System.Runtime.Versioning;
using WmiLight;
using Ryujinx.Common.Logging;
using System.Collections.Generic;
using System.Linq;
using System;
using System.Management;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
namespace Ryujinx.Common.SystemInfo
{
@ -13,21 +11,57 @@ namespace Ryujinx.Common.SystemInfo
{
internal WindowsSystemInfo()
{
try
{
using (WmiConnection connection = new())
{
(string cpuName, PhysicalCores) = GetCpuStatsLight(connection);
CpuName = $"{cpuName ?? GetCpuidCpuName()} ; {PhysicalCores} physical ; {LogicalCoreCount} logical";
CpuName = $"{GetCpuidCpuName() ?? GetCpuNameWMI()} ; {GetPhysicalCoreCount()} physical ; {LogicalCoreCount} logical";
(RamTotal, RamAvailable) = GetMemoryStats();
}
}
catch (Exception ex)
private static string GetCpuNameWMI()
{
Logger.Error?.Print(LogClass.Application, $"WmiLight isn't available : {ex.Message}");
ManagementObjectCollection cpuObjs = GetWMIObjects("root\\CIMV2", "SELECT Name FROM Win32_Processor");
if (cpuObjs != null)
{
foreach (var cpuObj in cpuObjs)
{
return cpuObj["Name"].ToString().Trim();
}
}
return Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER").Trim();
}
private static new int GetPhysicalCoreCount()
{
uint buffSize = 0;
GetLogicalProcessorInformation(IntPtr.Zero, ref buffSize);
IntPtr buffer = Marshal.AllocHGlobal((int)buffSize);
bool success = GetLogicalProcessorInformation(buffer, ref buffSize);
if (!success)
{
Marshal.FreeHGlobal(buffer);
return LogicalCoreCount;
}
int physicalCores = 0;
long pos = buffer.ToInt64();
int size = Marshal.SizeOf(typeof(SystemLogicalProcessorInformation));
for (long offset = 0; offset + size <= buffSize; offset += size)
{
IntPtr current = new IntPtr(pos + offset);
SystemLogicalProcessorInformation info = Marshal.PtrToStructure<SystemLogicalProcessorInformation>(current);
if (info.Relationship == LogicalProcessorRelationship.RelationProcessorCore)
{
physicalCores++;
}
}
Marshal.FreeHGlobal(buffer);
return physicalCores;
}
private static (ulong Total, ulong Available) GetMemoryStats()
{
MemoryStatusEx memStatus = new();
@ -41,23 +75,6 @@ namespace Ryujinx.Common.SystemInfo
return (0, 0);
}
private (string cpuName, int physicalCores) GetCpuStatsLight(WmiConnection connection)
{
string cpuName = Environment.GetEnvironmentVariable("PROCESSOR_IDENTIFIER")?.Trim();
int physicalCores = LogicalCoreCount;
foreach (WmiObject cpuObj in GetWmiObjects(connection, "SELECT Name FROM Win32_Processor"))
{
cpuName = cpuObj["Name"].ToString().Trim();
}
foreach (WmiObject cpuObj in GetWmiObjects(connection, "SELECT NumberOfCores FROM Win32_Processor"))
{
physicalCores = Convert.ToInt32(cpuObj["NumberOfCores"]);
}
return (cpuName, physicalCores);
}
[StructLayout(LayoutKind.Sequential)]
private struct MemoryStatusEx
{
@ -81,19 +98,45 @@ namespace Ryujinx.Common.SystemInfo
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool GlobalMemoryStatusEx(ref MemoryStatusEx lpBuffer);
private IEnumerable<WmiObject> GetWmiObjects(WmiConnection connection, string query)
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GetLogicalProcessorInformation(IntPtr buffer, ref uint returnLength);
[StructLayout(LayoutKind.Sequential)]
public struct SystemLogicalProcessorInformation
{
public UIntPtr ProcessorMask;
public LogicalProcessorRelationship Relationship;
public ProcessorInformationUnion ProcessorInformation;
}
[StructLayout(LayoutKind.Explicit)]
public struct ProcessorInformationUnion
{
[FieldOffset(8)]
private UInt64 Reserved2;
}
public enum LogicalProcessorRelationship
{
RelationProcessorCore,
}
private static ManagementObjectCollection GetWMIObjects(string scope, string query)
{
try
{
return connection.CreateQuery(query).ToList();
return new ManagementObjectSearcher(scope, query).Get();
}
catch (Exception ex)
catch (PlatformNotSupportedException ex)
{
Logger.Error?.Print(LogClass.Application, $"WmiLight isn't available : {ex.Message}");
Logger.Error?.Print(LogClass.Application, $"WMI isn't available : {ex.Message}");
}
catch (COMException ex)
{
Logger.Error?.Print(LogClass.Application, $"WMI isn't available : {ex.Message}");
}
return Enumerable.Empty<WmiObject>();
return null;
}
}
}

View file

@ -67,7 +67,6 @@
<PropertyGroup Condition="'$(RuntimeIdentifier)' != ''">
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<TrimMode>partial</TrimMode>
</PropertyGroup>
</Project>

View file

@ -16,7 +16,6 @@
<PublishSingleFile>true</PublishSingleFile>
<TrimmerSingleWarn>false</TrimmerSingleWarn>
<PublishTrimmed>true</PublishTrimmed>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<TrimMode>partial</TrimMode>
</PropertyGroup>