mirror of
https://github.com/openhardwaremonitor/openhardwaremonitor
synced 2025-08-22 09:57:20 +00:00
Added support for multiple processor groups. Changed the ThreadAffinity class to use a new struct GroupAffinity. Changed operating system checks to make use of a new flag OperatingSystem.IsUnix.
This commit is contained in:
parent
87c6f02d33
commit
b04c151c77
@ -130,8 +130,7 @@ namespace OpenHardwareMonitor.GUI {
|
||||
systemTray.HideShowCommand += hideShowClick;
|
||||
systemTray.ExitCommand += exitClick;
|
||||
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if ((p == 4) || (p == 128)) { // Unix
|
||||
if (Hardware.OperatingSystem.IsUnix) { // Unix
|
||||
treeView.RowHeight = Math.Max(treeView.RowHeight, 18);
|
||||
splitContainer.BorderStyle = BorderStyle.None;
|
||||
splitContainer.Border3DStyle = Border3DStyle.Adjust;
|
||||
|
@ -23,8 +23,7 @@ namespace OpenHardwareMonitor.GUI {
|
||||
private NotifyIconWindowsImplementation windowsNotifyIcon;
|
||||
|
||||
public NotifyIconAdv() {
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if ((p == 4) || (p == 128)) { // Unix
|
||||
if (Hardware.OperatingSystem.IsUnix) { // Unix
|
||||
genericNotifyIcon = new NotifyIcon();
|
||||
} else { // Windows
|
||||
windowsNotifyIcon = new NotifyIconWindowsImplementation();
|
||||
|
@ -39,8 +39,7 @@ namespace OpenHardwareMonitor.GUI {
|
||||
}
|
||||
|
||||
public StartupManager() {
|
||||
int p = (int)System.Environment.OSVersion.Platform;
|
||||
if ((p == 4) || (p == 128)) {
|
||||
if (Hardware.OperatingSystem.IsUnix) {
|
||||
scheduler = null;
|
||||
isAvailable = false;
|
||||
return;
|
||||
|
@ -431,8 +431,7 @@ namespace OpenHardwareMonitor.Hardware.ATI {
|
||||
}
|
||||
|
||||
private static void CreateDelegates(string name) {
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if ((p == 4) || (p == 128))
|
||||
if (OperatingSystem.IsUnix)
|
||||
dllName = name + ".so";
|
||||
else
|
||||
dllName = name + ".dll";
|
||||
|
@ -130,7 +130,8 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
|
||||
uint eax, edx;
|
||||
if (Ring0.RdmsrTx(FIDVID_STATUS, out eax, out edx,
|
||||
1UL << cpuid[i][0].Thread)) {
|
||||
cpuid[i][0].Affinity))
|
||||
{
|
||||
// CurrFID can be found in eax bits 0-5, MaxFID in 16-21
|
||||
// 8-13 hold StartFID, we don't use that here.
|
||||
double curMP = 0.5 * ((eax & 0x3F) + 8);
|
||||
|
@ -108,7 +108,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
corePerformanceBoostSupport = (cpuid[0][0].ExtData[7, 3] & (1 << 9)) > 0;
|
||||
|
||||
// set affinity to the first thread for all frequency estimations
|
||||
ulong mask = ThreadAffinity.Set(1UL << cpuid[0][0].Thread);
|
||||
var previousAffinity = ThreadAffinity.Set(cpuid[0][0].Affinity);
|
||||
|
||||
// disable core performance boost
|
||||
uint hwcrEax, hwcrEdx;
|
||||
@ -132,12 +132,11 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
Ring0.Wrmsr(HWCR, hwcrEax, hwcrEdx);
|
||||
|
||||
// restore the thread affinity.
|
||||
ThreadAffinity.Set(mask);
|
||||
ThreadAffinity.Set(previousAffinity);
|
||||
|
||||
// the file reader for lm-sensors support on Linux
|
||||
temperatureStream = null;
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if ((p == 4) || (p == 128)) {
|
||||
if (OperatingSystem.IsUnix) {
|
||||
string[] devicePaths = Directory.GetDirectories("/sys/class/hwmon/");
|
||||
foreach (string path in devicePaths) {
|
||||
string name = null;
|
||||
@ -346,7 +345,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
|
||||
uint curEax, curEdx;
|
||||
if (Ring0.RdmsrTx(COFVID_STATUS, out curEax, out curEdx,
|
||||
1UL << cpuid[i][0].Thread))
|
||||
cpuid[i][0].Affinity))
|
||||
{
|
||||
double multiplier;
|
||||
multiplier = GetCoreMultiplier(curEax);
|
||||
|
@ -272,7 +272,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
private class Core {
|
||||
|
||||
private readonly AMD17CPU cpu;
|
||||
private readonly ulong threadAffinityMask;
|
||||
private readonly GroupAffinity affinity;
|
||||
|
||||
private readonly Sensor powerSensor;
|
||||
private readonly Sensor clockSensor;
|
||||
@ -284,7 +284,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
public Core(int index, CPUID[] threads, AMD17CPU cpu, ISettings settings)
|
||||
{
|
||||
this.cpu = cpu;
|
||||
this.threadAffinityMask = 1UL << threads[0].Thread;
|
||||
this.affinity = threads[0].Affinity;
|
||||
|
||||
string coreString = cpu.CoreString(index);
|
||||
this.powerSensor =
|
||||
@ -294,7 +294,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
|
||||
if (cpu.energyUnitMultiplier != 0) {
|
||||
if (Ring0.RdmsrTx(MSR_CORE_ENERGY_STAT, out uint energyConsumed,
|
||||
out _, threadAffinityMask))
|
||||
out _, affinity))
|
||||
{
|
||||
lastEnergyTime = DateTime.UtcNow;
|
||||
lastEnergyConsumed = energyConsumed;
|
||||
@ -319,13 +319,13 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
DateTime energyTime = DateTime.MinValue;
|
||||
double? multiplier = null;
|
||||
|
||||
ulong mask = ThreadAffinity.Set(threadAffinityMask);
|
||||
var previousAffinity = ThreadAffinity.Set(affinity);
|
||||
if (Ring0.Rdmsr(MSR_CORE_ENERGY_STAT, out uint energyConsumed, out _)) {
|
||||
energyTime = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
multiplier = GetMultiplier();
|
||||
ThreadAffinity.Set(mask);
|
||||
ThreadAffinity.Set(previousAffinity);
|
||||
|
||||
if (cpu.energyUnitMultiplier != 0) {
|
||||
float deltaTime = (float)(energyTime - lastEnergyTime).TotalSeconds;
|
||||
|
@ -23,10 +23,17 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
private static CPUID[][] GetProcessorThreads() {
|
||||
|
||||
List<CPUID> threads = new List<CPUID>();
|
||||
for (int i = 0; i < 64; i++) {
|
||||
for (int i = 0; i < ThreadAffinity.ProcessorGroupCount; i++) {
|
||||
for (int j = 0; j < 64; j++) {
|
||||
try {
|
||||
threads.Add(new CPUID(i));
|
||||
} catch (ArgumentOutOfRangeException) { }
|
||||
if (!ThreadAffinity.IsValid(GroupAffinity.Single((ushort)i, j)))
|
||||
continue;
|
||||
var cpuid = CPUID.Get(i, j);
|
||||
if (cpuid != null)
|
||||
threads.Add(cpuid);
|
||||
} catch (ArgumentOutOfRangeException) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SortedDictionary<uint, List<CPUID>> processors =
|
||||
@ -172,6 +179,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
r.AppendLine();
|
||||
for (int j = 0; j < threads[i].Length; j++)
|
||||
for (int k = 0; k < threads[i][j].Length; k++) {
|
||||
r.AppendLine(" CPU Group: " + threads[i][j][k].Group);
|
||||
r.AppendLine(" CPU Thread: " + threads[i][j][k].Thread);
|
||||
r.AppendLine(" APIC ID: " + threads[i][j][k].ApicId);
|
||||
r.AppendLine(" Processor ID: " + threads[i][j][k].ProcessorId);
|
||||
|
@ -21,7 +21,9 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
|
||||
internal class CPUID {
|
||||
|
||||
private readonly int group;
|
||||
private readonly int thread;
|
||||
private readonly GroupAffinity affinity;
|
||||
|
||||
private readonly Vendor vendor = Vendor.Unknown;
|
||||
|
||||
@ -68,20 +70,34 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
return count;
|
||||
}
|
||||
|
||||
public CPUID(int thread) {
|
||||
public static CPUID Get(int group, int thread) {
|
||||
if (thread >= 64)
|
||||
return null;
|
||||
|
||||
var affinity = GroupAffinity.Single((ushort)group, thread);
|
||||
|
||||
var previousAffinity = ThreadAffinity.Set(affinity);
|
||||
if (previousAffinity == GroupAffinity.Undefined)
|
||||
return null;
|
||||
|
||||
try {
|
||||
return new CPUID(group, thread, affinity);
|
||||
} finally {
|
||||
ThreadAffinity.Set(previousAffinity);
|
||||
}
|
||||
}
|
||||
|
||||
private CPUID(int group, int thread, GroupAffinity affinity) {
|
||||
this.group = group;
|
||||
this.thread = thread;
|
||||
this.affinity = affinity;
|
||||
|
||||
uint maxCpuid = 0;
|
||||
uint maxCpuidExt = 0;
|
||||
|
||||
uint eax, ebx, ecx, edx;
|
||||
|
||||
if (thread >= 64)
|
||||
throw new ArgumentOutOfRangeException("thread");
|
||||
ulong mask = 1UL << thread;
|
||||
|
||||
if (Opcode.CpuidTx(CPUID_0, 0,
|
||||
out eax, out ebx, out ecx, out edx, mask)) {
|
||||
Opcode.Cpuid(CPUID_0, 0, out eax, out ebx, out ecx, out edx);
|
||||
if (eax > 0)
|
||||
maxCpuid = eax;
|
||||
else
|
||||
@ -104,45 +120,35 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
break;
|
||||
}
|
||||
eax = ebx = ecx = edx = 0;
|
||||
if (Opcode.CpuidTx(CPUID_EXT, 0,
|
||||
out eax, out ebx, out ecx, out edx, mask)) {
|
||||
Opcode.Cpuid(CPUID_EXT, 0, out eax, out ebx, out ecx, out edx);
|
||||
if (eax > CPUID_EXT)
|
||||
maxCpuidExt = eax - CPUID_EXT;
|
||||
else
|
||||
return;
|
||||
} else {
|
||||
throw new ArgumentOutOfRangeException("thread");
|
||||
}
|
||||
} else {
|
||||
throw new ArgumentOutOfRangeException("thread");
|
||||
}
|
||||
|
||||
maxCpuid = Math.Min(maxCpuid, 1024);
|
||||
maxCpuidExt = Math.Min(maxCpuidExt, 1024);
|
||||
|
||||
cpuidData = new uint[maxCpuid + 1, 4];
|
||||
for (uint i = 0; i < (maxCpuid + 1); i++)
|
||||
Opcode.CpuidTx(CPUID_0 + i, 0,
|
||||
Opcode.Cpuid(CPUID_0 + i, 0,
|
||||
out cpuidData[i, 0], out cpuidData[i, 1],
|
||||
out cpuidData[i, 2], out cpuidData[i, 3], mask);
|
||||
out cpuidData[i, 2], out cpuidData[i, 3]);
|
||||
|
||||
cpuidExtData = new uint[maxCpuidExt + 1, 4];
|
||||
for (uint i = 0; i < (maxCpuidExt + 1); i++)
|
||||
Opcode.CpuidTx(CPUID_EXT + i, 0,
|
||||
Opcode.Cpuid(CPUID_EXT + i, 0,
|
||||
out cpuidExtData[i, 0], out cpuidExtData[i, 1],
|
||||
out cpuidExtData[i, 2], out cpuidExtData[i, 3], mask);
|
||||
out cpuidExtData[i, 2], out cpuidExtData[i, 3]);
|
||||
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
for (uint i = 2; i <= 4; i++) {
|
||||
if (Opcode.CpuidTx(CPUID_EXT + i, 0,
|
||||
out eax, out ebx, out ecx, out edx, mask))
|
||||
{
|
||||
Opcode.Cpuid(CPUID_EXT + i, 0, out eax, out ebx, out ecx, out edx);
|
||||
AppendRegister(nameBuilder, eax);
|
||||
AppendRegister(nameBuilder, ebx);
|
||||
AppendRegister(nameBuilder, ecx);
|
||||
AppendRegister(nameBuilder, edx);
|
||||
}
|
||||
}
|
||||
nameBuilder.Replace('\0', ' ');
|
||||
cpuBrandString = nameBuilder.ToString().Trim();
|
||||
nameBuilder.Replace("Dual-Core Processor", "");
|
||||
@ -250,10 +256,22 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
get { return cpuBrandString; }
|
||||
}
|
||||
|
||||
public int Group {
|
||||
get {
|
||||
return group;
|
||||
}
|
||||
}
|
||||
|
||||
public int Thread {
|
||||
get { return thread; }
|
||||
}
|
||||
|
||||
public GroupAffinity Affinity {
|
||||
get {
|
||||
return affinity;
|
||||
}
|
||||
}
|
||||
|
||||
public Vendor Vendor {
|
||||
get { return vendor; }
|
||||
}
|
||||
|
@ -106,13 +106,13 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
}
|
||||
|
||||
if (hasTimeStampCounter) {
|
||||
ulong mask = ThreadAffinity.Set(1UL << cpuid[0][0].Thread);
|
||||
var previousAffinity = ThreadAffinity.Set(cpuid[0][0].Affinity);
|
||||
|
||||
EstimateTimeStampCounterFrequency(
|
||||
out estimatedTimeStampCounterFrequency,
|
||||
out estimatedTimeStampCounterFrequencyError);
|
||||
|
||||
ThreadAffinity.Set(mask);
|
||||
ThreadAffinity.Set(previousAffinity);
|
||||
} else {
|
||||
estimatedTimeStampCounterFrequency = 0;
|
||||
}
|
||||
@ -185,9 +185,11 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
}
|
||||
|
||||
|
||||
private static void AppendMSRData(StringBuilder r, uint msr, int thread) {
|
||||
private static void AppendMSRData(StringBuilder r, uint msr,
|
||||
GroupAffinity affinity)
|
||||
{
|
||||
uint eax, edx;
|
||||
if (Ring0.RdmsrTx(msr, out eax, out edx, 1UL << thread)) {
|
||||
if (Ring0.RdmsrTx(msr, out eax, out edx, affinity)) {
|
||||
r.Append(" ");
|
||||
r.Append((msr).ToString("X8", CultureInfo.InvariantCulture));
|
||||
r.Append(" ");
|
||||
@ -240,7 +242,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
r.AppendLine();
|
||||
r.AppendLine(" MSR EDX EAX");
|
||||
foreach (uint msr in msrArray)
|
||||
AppendMSRData(r, msr, cpuid[i][0].Thread);
|
||||
AppendMSRData(r, msr, cpuid[i][0].Affinity);
|
||||
r.AppendLine();
|
||||
}
|
||||
}
|
||||
@ -268,15 +270,15 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
if (hasTimeStampCounter && isInvariantTimeStampCounter) {
|
||||
|
||||
// make sure always the same thread is used
|
||||
ulong mask = ThreadAffinity.Set(1UL << cpuid[0][0].Thread);
|
||||
var previousAffinity = ThreadAffinity.Set(cpuid[0][0].Affinity);
|
||||
|
||||
// read time before and after getting the TSC to estimate the error
|
||||
long firstTime = Stopwatch.GetTimestamp();
|
||||
ulong timeStampCount = Opcode.Rdtsc();
|
||||
long time = Stopwatch.GetTimestamp();
|
||||
|
||||
// restore the thread affinity mask
|
||||
ThreadAffinity.Set(mask);
|
||||
// restore the previous thread affinity mask
|
||||
ThreadAffinity.Set(previousAffinity);
|
||||
|
||||
double delta = ((double)(time - lastTime)) / Stopwatch.Frequency;
|
||||
double error = ((double)(time - firstTime)) / Stopwatch.Frequency;
|
||||
|
@ -79,7 +79,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
float[] result = new float[coreCount];
|
||||
for (int i = 0; i < coreCount; i++) {
|
||||
if (Ring0.RdmsrTx(IA32_TEMPERATURE_TARGET, out eax,
|
||||
out edx, 1UL << cpuid[i][0].Thread)) {
|
||||
out edx, cpuid[i][0].Affinity)) {
|
||||
result[i] = (eax >> 16) & 0xFF;
|
||||
} else {
|
||||
result[i] = 100;
|
||||
@ -419,7 +419,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
uint eax, edx;
|
||||
// if reading is valid
|
||||
if (Ring0.RdmsrTx(IA32_THERM_STATUS_MSR, out eax, out edx,
|
||||
1UL << cpuid[i][0].Thread) && (eax & 0x80000000) != 0)
|
||||
cpuid[i][0].Affinity) && (eax & 0x80000000) != 0)
|
||||
{
|
||||
// get the dist from tjMax from bits 22:16
|
||||
float deltaT = ((eax & 0x007F0000) >> 16);
|
||||
@ -435,7 +435,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
uint eax, edx;
|
||||
// if reading is valid
|
||||
if (Ring0.RdmsrTx(IA32_PACKAGE_THERM_STATUS, out eax, out edx,
|
||||
1UL << cpuid[0][0].Thread) && (eax & 0x80000000) != 0)
|
||||
cpuid[0][0].Affinity) && (eax & 0x80000000) != 0)
|
||||
{
|
||||
// get the dist from tjMax from bits 22:16
|
||||
float deltaT = ((eax & 0x007F0000) >> 16);
|
||||
@ -453,7 +453,8 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
for (int i = 0; i < coreClocks.Length; i++) {
|
||||
System.Threading.Thread.Sleep(1);
|
||||
if (Ring0.RdmsrTx(IA32_PERF_STATUS, out eax, out edx,
|
||||
1UL << cpuid[i][0].Thread)) {
|
||||
cpuid[i][0].Affinity))
|
||||
{
|
||||
newBusClock =
|
||||
TimeStampCounterFrequency / timeStampCounterMultiplier;
|
||||
switch (microarchitecture) {
|
||||
|
57
Hardware/GroupAffinity.cs
Normal file
57
Hardware/GroupAffinity.cs
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
Copyright (C) 2020 Michael Möller <mmoeller@openhardwaremonitor.org>
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenHardwareMonitor.Hardware {
|
||||
|
||||
/// <summary>
|
||||
/// This structure describes a group-specific affinity.
|
||||
/// </summary>
|
||||
internal struct GroupAffinity {
|
||||
|
||||
public static GroupAffinity Undefined =
|
||||
new GroupAffinity(ushort.MaxValue, 0);
|
||||
|
||||
public GroupAffinity(ushort group, ulong mask) {
|
||||
this.Group = group;
|
||||
this.Mask = mask;
|
||||
}
|
||||
|
||||
public static GroupAffinity Single(ushort group, int index) {
|
||||
return new GroupAffinity(group, 1UL << index);
|
||||
}
|
||||
|
||||
public ushort Group { get; }
|
||||
|
||||
public ulong Mask { get; }
|
||||
|
||||
public override bool Equals(object o) {
|
||||
if (o == null || GetType() != o.GetType()) return false;
|
||||
GroupAffinity a = (GroupAffinity)o;
|
||||
return (Group == a.Group) && (Mask == a.Mask);
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return Group.GetHashCode() ^ Mask.GetHashCode();
|
||||
}
|
||||
|
||||
public static bool operator ==(GroupAffinity a1, GroupAffinity a2) {
|
||||
return (a1.Group == a2.Group) && (a1.Mask == a2.Mask);
|
||||
}
|
||||
|
||||
public static bool operator !=(GroupAffinity a1, GroupAffinity a2) {
|
||||
return (a1.Group != a2.Group) || (a1.Mask != a2.Mask);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -24,8 +24,8 @@ namespace OpenHardwareMonitor.Hardware.HDD {
|
||||
new List<AbstractHarddrive>();
|
||||
|
||||
public HarddriveGroup(ISettings settings) {
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if (p == 4 || p == 128) return;
|
||||
if (OperatingSystem.IsUnix)
|
||||
return;
|
||||
|
||||
ISmart smart = new WindowsSmart();
|
||||
|
||||
|
@ -67,8 +67,7 @@ namespace OpenHardwareMonitor.Hardware.Heatmaster {
|
||||
public HeatmasterGroup(ISettings settings) {
|
||||
|
||||
// No implementation for Heatmaster on Unix systems
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if ((p == 4) || (p == 128))
|
||||
if (OperatingSystem.IsUnix)
|
||||
return;
|
||||
|
||||
string[] portNames = GetRegistryPortNames();
|
||||
|
@ -50,8 +50,7 @@ namespace OpenHardwareMonitor.Hardware.Mainboard {
|
||||
new Identifier(Identifier, "name").ToString(), name);
|
||||
|
||||
ISuperIO[] superIO;
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if ((p == 4) || (p == 128)) {
|
||||
if (OperatingSystem.IsUnix) {
|
||||
this.lmSensors = new LMSensors();
|
||||
superIO = lmSensors.SuperIO;
|
||||
} else {
|
||||
|
@ -61,8 +61,7 @@ namespace OpenHardwareMonitor.Hardware.Nvidia {
|
||||
}
|
||||
|
||||
private static string GetDllName() {
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if ((p == 4) || (p == 128))
|
||||
if (OperatingSystem.IsUnix)
|
||||
return "libnvidia-ml.so";
|
||||
else
|
||||
return "nvml.dll";
|
||||
|
@ -19,8 +19,6 @@ namespace OpenHardwareMonitor.Hardware {
|
||||
private static ulong size;
|
||||
|
||||
public static void Open() {
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
|
||||
byte[] rdtscCode;
|
||||
byte[] cpuidCode;
|
||||
if (IntPtr.Size == 4) {
|
||||
@ -29,7 +27,7 @@ namespace OpenHardwareMonitor.Hardware {
|
||||
} else {
|
||||
rdtscCode = RDTSC_64;
|
||||
|
||||
if ((p == 4) || (p == 128)) { // Unix
|
||||
if (OperatingSystem.IsUnix) { // Unix
|
||||
cpuidCode = CPUID_64_LINUX;
|
||||
} else { // Windows
|
||||
cpuidCode = CPUID_64_WINDOWS;
|
||||
@ -38,7 +36,7 @@ namespace OpenHardwareMonitor.Hardware {
|
||||
|
||||
size = (ulong)(rdtscCode.Length + cpuidCode.Length);
|
||||
|
||||
if ((p == 4) || (p == 128)) { // Unix
|
||||
if (OperatingSystem.IsUnix) { // Unix
|
||||
Assembly assembly =
|
||||
Assembly.Load("Mono.Posix, Version=2.0.0.0, Culture=neutral, " +
|
||||
"PublicKeyToken=0738eb9f132ed756");
|
||||
@ -81,8 +79,7 @@ namespace OpenHardwareMonitor.Hardware {
|
||||
Rdtsc = null;
|
||||
Cpuid = null;
|
||||
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if ((p == 4) || (p == 128)) { // Unix
|
||||
if (OperatingSystem.IsUnix) { // Unix
|
||||
Assembly assembly =
|
||||
Assembly.Load("Mono.Posix, Version=2.0.0.0, Culture=neutral, " +
|
||||
"PublicKeyToken=0738eb9f132ed756");
|
||||
@ -201,18 +198,18 @@ namespace OpenHardwareMonitor.Hardware {
|
||||
|
||||
public static bool CpuidTx(uint index, uint ecxValue,
|
||||
out uint eax, out uint ebx, out uint ecx, out uint edx,
|
||||
ulong threadAffinityMask) {
|
||||
GroupAffinity affinity)
|
||||
{
|
||||
var previousAffinity = ThreadAffinity.Set(affinity);
|
||||
|
||||
ulong mask = ThreadAffinity.Set(threadAffinityMask);
|
||||
|
||||
if (mask == 0) {
|
||||
if (previousAffinity == GroupAffinity.Undefined) {
|
||||
eax = ebx = ecx = edx = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
Cpuid(index, ecxValue, out eax, out ebx, out ecx, out edx);
|
||||
|
||||
ThreadAffinity.Set(mask);
|
||||
ThreadAffinity.Set(previousAffinity);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
Copyright (C) 2012 Michael Möller <mmoeller@openhardwaremonitor.org>
|
||||
Copyright (C) 2012-2020 Michael Möller <mmoeller@openhardwaremonitor.org>
|
||||
|
||||
*/
|
||||
|
||||
@ -13,9 +13,20 @@ using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace OpenHardwareMonitor.Hardware {
|
||||
internal static class OperatingSystem {
|
||||
public static class OperatingSystem {
|
||||
|
||||
public static bool Is64BitOperatingSystem() {
|
||||
static OperatingSystem() {
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
IsUnix = (p == 4) || (p == 6) || (p == 128);
|
||||
|
||||
Is64BitOperatingSystem = GetIs64BitOperatingSystem();
|
||||
}
|
||||
|
||||
public static bool IsUnix { get; }
|
||||
|
||||
public static bool Is64BitOperatingSystem { get; }
|
||||
|
||||
private static bool GetIs64BitOperatingSystem() {
|
||||
if (IntPtr.Size == 8)
|
||||
return true;
|
||||
|
||||
|
@ -18,8 +18,7 @@ namespace OpenHardwareMonitor.Hardware.RAM {
|
||||
public RAMGroup(SMBIOS smbios, ISettings settings) {
|
||||
|
||||
// No implementation for RAM on Unix systems
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if ((p == 4) || (p == 128)) {
|
||||
if (OperatingSystem.IsUnix) {
|
||||
hardware = new Hardware[0];
|
||||
return;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
Copyright (C) 2010-2016 Michael Möller <mmoeller@openhardwaremonitor.org>
|
||||
Copyright (C) 2010-2020 Michael Möller <mmoeller@openhardwaremonitor.org>
|
||||
|
||||
*/
|
||||
|
||||
@ -80,7 +80,7 @@ namespace OpenHardwareMonitor.Hardware {
|
||||
|
||||
private static bool ExtractDriver(string fileName) {
|
||||
string resourceName = "OpenHardwareMonitor.Hardware." +
|
||||
(OperatingSystem.Is64BitOperatingSystem() ? "WinRing0x64.sys" :
|
||||
(OperatingSystem.Is64BitOperatingSystem ? "WinRing0x64.sys" :
|
||||
"WinRing0.sys");
|
||||
|
||||
string[] names = GetAssembly().GetManifestResourceNames();
|
||||
@ -129,8 +129,7 @@ namespace OpenHardwareMonitor.Hardware {
|
||||
|
||||
public static void Open() {
|
||||
// no implementation for unix systems
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if ((p == 4) || (p == 128))
|
||||
if (OperatingSystem.IsUnix)
|
||||
return;
|
||||
|
||||
if (driver != null)
|
||||
@ -284,13 +283,13 @@ namespace OpenHardwareMonitor.Hardware {
|
||||
}
|
||||
|
||||
public static bool RdmsrTx(uint index, out uint eax, out uint edx,
|
||||
ulong threadAffinityMask)
|
||||
GroupAffinity affinity)
|
||||
{
|
||||
ulong mask = ThreadAffinity.Set(threadAffinityMask);
|
||||
var previousAffinity = ThreadAffinity.Set(affinity);
|
||||
|
||||
bool result = Rdmsr(index, out eax, out edx);
|
||||
|
||||
ThreadAffinity.Set(mask);
|
||||
ThreadAffinity.Set(previousAffinity);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -42,8 +42,7 @@ namespace OpenHardwareMonitor.Hardware {
|
||||
}
|
||||
|
||||
public SMBIOS() {
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if ((p == 4) || (p == 128)) {
|
||||
if (OperatingSystem.IsUnix) {
|
||||
this.raw = null;
|
||||
this.table = null;
|
||||
|
||||
|
@ -184,8 +184,7 @@ namespace OpenHardwareMonitor.Hardware.TBalancer {
|
||||
}
|
||||
|
||||
private static string GetDllName() {
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if ((p == 4) || (p == 128))
|
||||
if (OperatingSystem.IsUnix)
|
||||
return "libftd2xx.so";
|
||||
else
|
||||
return "ftd2xx.dll";
|
||||
|
@ -4,7 +4,7 @@
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
Copyright (C) 2010-2014 Michael Möller <mmoeller@openhardwaremonitor.org>
|
||||
Copyright (C) 2010-2020 Michael Möller <mmoeller@openhardwaremonitor.org>
|
||||
|
||||
*/
|
||||
|
||||
@ -15,29 +15,95 @@ namespace OpenHardwareMonitor.Hardware {
|
||||
|
||||
internal static class ThreadAffinity {
|
||||
|
||||
public static ulong Set(ulong mask) {
|
||||
if (mask == 0)
|
||||
return 0;
|
||||
static ThreadAffinity() {
|
||||
ProcessorGroupCount = GetProcessorGroupCount();
|
||||
}
|
||||
|
||||
private static int GetProcessorGroupCount() {
|
||||
if (OperatingSystem.IsUnix)
|
||||
return 1;
|
||||
|
||||
try {
|
||||
return NativeMethods.GetActiveProcessorGroupCount();
|
||||
} catch {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static int ProcessorGroupCount { get; }
|
||||
|
||||
public static bool IsValid(GroupAffinity affinity) {
|
||||
if (OperatingSystem.IsUnix) {
|
||||
if (affinity.Group > 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
var previous = Set(affinity);
|
||||
if (previous == GroupAffinity.Undefined)
|
||||
return false;
|
||||
Set(previous);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the processor group affinity for the current thread.
|
||||
/// </summary>
|
||||
/// <param name="affinity">The processor group affinity.</param>
|
||||
/// <returns>The previous processor group affinity.</returns>
|
||||
public static GroupAffinity Set(GroupAffinity affinity) {
|
||||
if (affinity == GroupAffinity.Undefined)
|
||||
return GroupAffinity.Undefined;
|
||||
|
||||
if (OperatingSystem.IsUnix) {
|
||||
if (affinity.Group > 0)
|
||||
throw new ArgumentOutOfRangeException("affinity.Group");
|
||||
|
||||
int p = (int)Environment.OSVersion.Platform;
|
||||
if ((p == 4) || (p == 128)) { // Unix
|
||||
ulong result = 0;
|
||||
if (NativeMethods.sched_getaffinity(0, (IntPtr)Marshal.SizeOf(result),
|
||||
ref result) != 0)
|
||||
return 0;
|
||||
if (NativeMethods.sched_setaffinity(0, (IntPtr)Marshal.SizeOf(mask),
|
||||
ref mask) != 0)
|
||||
return 0;
|
||||
return result;
|
||||
} else { // Windows
|
||||
if (NativeMethods.sched_getaffinity(0, (IntPtr)8, ref result) != 0)
|
||||
return GroupAffinity.Undefined;
|
||||
|
||||
ulong mask = affinity.Mask;
|
||||
if (NativeMethods.sched_setaffinity(0, (IntPtr)8, ref mask) != 0)
|
||||
return GroupAffinity.Undefined;
|
||||
|
||||
return new GroupAffinity(0, result);
|
||||
} else {
|
||||
UIntPtr uIntPtrMask;
|
||||
try {
|
||||
uIntPtrMask = (UIntPtr)mask;
|
||||
uIntPtrMask = (UIntPtr)affinity.Mask;
|
||||
} catch (OverflowException) {
|
||||
throw new ArgumentOutOfRangeException("mask");
|
||||
throw new ArgumentOutOfRangeException("affinity.Mask");
|
||||
}
|
||||
|
||||
var groupAffinity = new NativeMethods.GROUP_AFFINITY {
|
||||
Group = affinity.Group,
|
||||
Mask = uIntPtrMask
|
||||
};
|
||||
|
||||
var currentThread = NativeMethods.GetCurrentThread();
|
||||
|
||||
try {
|
||||
if (NativeMethods.SetThreadGroupAffinity(currentThread,
|
||||
ref groupAffinity, out var previousGroupAffinity))
|
||||
{
|
||||
return new GroupAffinity(previousGroupAffinity.Group,
|
||||
(ulong)previousGroupAffinity.Mask);
|
||||
} else {
|
||||
return GroupAffinity.Undefined;
|
||||
}
|
||||
} catch (EntryPointNotFoundException) {
|
||||
if (affinity.Group > 0)
|
||||
throw new ArgumentOutOfRangeException("affinity.Group");
|
||||
|
||||
var previous = (ulong)NativeMethods.SetThreadAffinityMask(
|
||||
currentThread, uIntPtrMask);
|
||||
|
||||
return new GroupAffinity(0, previous);
|
||||
}
|
||||
return (ulong)NativeMethods.SetThreadAffinityMask(
|
||||
NativeMethods.GetCurrentThread(), uIntPtrMask);
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +117,25 @@ namespace OpenHardwareMonitor.Hardware {
|
||||
[DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern IntPtr GetCurrentThread();
|
||||
|
||||
[DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern ushort GetActiveProcessorGroupCount();
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct GROUP_AFFINITY {
|
||||
public UIntPtr Mask;
|
||||
[MarshalAs(UnmanagedType.U2)]
|
||||
public ushort Group;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3,
|
||||
ArraySubType = UnmanagedType.U2)]
|
||||
public ushort[] Reserved;
|
||||
}
|
||||
|
||||
[DllImport(KERNEL, CallingConvention = CallingConvention.Winapi)]
|
||||
public static extern bool SetThreadGroupAffinity(
|
||||
IntPtr thread,
|
||||
ref GROUP_AFFINITY groupAffinity,
|
||||
out GROUP_AFFINITY previousGroupAffinity);
|
||||
|
||||
private const string LIBC = "libc";
|
||||
|
||||
[DllImport(LIBC)]
|
||||
|
@ -64,6 +64,7 @@
|
||||
<Compile Include="Hardware\Control.cs" />
|
||||
<Compile Include="Hardware\CPU\AMD17CPU.cs" />
|
||||
<Compile Include="Hardware\FirmwareTable.cs" />
|
||||
<Compile Include="Hardware\GroupAffinity.cs" />
|
||||
<Compile Include="Hardware\HDD\DebugSmart.cs" />
|
||||
<Compile Include="Hardware\HDD\DriveAttributeValue.cs" />
|
||||
<Compile Include="Hardware\HDD\DriveThresholdValue.cs" />
|
||||
|
@ -10,5 +10,5 @@
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion("0.9.2.3")]
|
||||
[assembly: AssemblyInformationalVersion("0.9.2.3 Alpha")]
|
||||
[assembly: AssemblyVersion("0.9.2.4")]
|
||||
[assembly: AssemblyInformationalVersion("0.9.2.4 Alpha")]
|
Loading…
x
Reference in New Issue
Block a user