Release version 0.1.13. Replaced PerformanceCounter based CPU load sensors with an implementation using NtQuerySystemInformation. Fixed a temperature reading problem for W83627DHG chips (sensors with invalid value 127°C).
This commit is contained in:
+18
-37
@@ -58,8 +58,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
|
||||
private List<ISensor> active = new List<ISensor>();
|
||||
|
||||
private PerformanceCounter totalLoadCounter;
|
||||
private PerformanceCounter[] coreLoadCounters;
|
||||
private CPULoad cpuLoad;
|
||||
|
||||
private const ushort PCI_AMD_VENDOR_ID = 0x1022;
|
||||
private const ushort PCI_AMD_0FH_MISCELLANEOUS_DEVICE_ID = 0x1103;
|
||||
@@ -80,37 +79,23 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
// max two cores
|
||||
coreCount = coreCount > 2 ? 2 : coreCount;
|
||||
|
||||
try {
|
||||
totalLoadCounter = new PerformanceCounter();
|
||||
totalLoadCounter.CategoryName = "Processor";
|
||||
totalLoadCounter.CounterName = "% Processor Time";
|
||||
totalLoadCounter.InstanceName = "_Total";
|
||||
totalLoadCounter.NextValue();
|
||||
} catch (Exception) {
|
||||
totalLoadCounter = null;
|
||||
}
|
||||
totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
|
||||
|
||||
coreLoadCounters = new PerformanceCounter[coreCount];
|
||||
|
||||
coreTemperatures = new Sensor[coreCount];
|
||||
coreLoads = new Sensor[coreCount];
|
||||
for (int i = 0; i < coreLoadCounters.Length; i++) {
|
||||
try {
|
||||
coreLoadCounters[i] = new PerformanceCounter();
|
||||
coreLoadCounters[i].CategoryName = "Processor";
|
||||
coreLoadCounters[i].CounterName = "% Processor Time";
|
||||
coreLoadCounters[i].InstanceName = i.ToString();
|
||||
coreLoadCounters[i].NextValue();
|
||||
} catch (Exception) {
|
||||
coreLoadCounters[i] = null;
|
||||
}
|
||||
for (int i = 0; i < coreCount; i++) {
|
||||
coreTemperatures[i] =
|
||||
new Sensor("Core #" + (i + 1), i, SensorType.Temperature, this);
|
||||
coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
|
||||
SensorType.Load, this);
|
||||
}
|
||||
}
|
||||
|
||||
coreTemperatures = new Sensor[coreCount];
|
||||
for (int i = 0; i < coreCount; i++)
|
||||
coreTemperatures[i] =
|
||||
new Sensor("Core #" + (i + 1), i, SensorType.Temperature, this);
|
||||
cpuLoad = new CPULoad(coreCount, 1);
|
||||
if (cpuLoad.IsAvailable) {
|
||||
foreach (Sensor sensor in coreLoads)
|
||||
ActivateSensor(sensor);
|
||||
ActivateSensor(totalLoad);
|
||||
}
|
||||
|
||||
pciAddress = WinRing0.FindPciDeviceById(PCI_AMD_VENDOR_ID,
|
||||
PCI_AMD_0FH_MISCELLANEOUS_DEVICE_ID, 0);
|
||||
@@ -163,16 +148,12 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
}
|
||||
}
|
||||
|
||||
if (totalLoadCounter != null) {
|
||||
totalLoad.Value = totalLoadCounter.NextValue();
|
||||
ActivateSensor(totalLoad);
|
||||
if (cpuLoad.IsAvailable) {
|
||||
cpuLoad.Update();
|
||||
for (int i = 0; i < coreLoads.Length; i++)
|
||||
coreLoads[i].Value = cpuLoad.GetCoreLoad(i);
|
||||
totalLoad.Value = cpuLoad.GetTotalLoad();
|
||||
}
|
||||
|
||||
for (int i = 0; i < coreLoads.Length; i++)
|
||||
if (coreLoadCounters[i] != null) {
|
||||
coreLoads[i].Value = coreLoadCounters[i].NextValue();
|
||||
ActivateSensor(coreLoads[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void ActivateSensor(Sensor sensor) {
|
||||
|
||||
+14
-32
@@ -55,8 +55,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
|
||||
private List<ISensor> active = new List<ISensor>();
|
||||
|
||||
private PerformanceCounter totalLoadCounter;
|
||||
private PerformanceCounter[] coreLoadCounters;
|
||||
private CPULoad cpuLoad;
|
||||
|
||||
private const ushort PCI_AMD_VENDOR_ID = 0x1022;
|
||||
private const ushort PCI_AMD_10H_MISCELLANEOUS_DEVICE_ID = 0x1203;
|
||||
@@ -72,32 +71,19 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
if (cpuidExtData.GetLength(0) > 8)
|
||||
coreCount = (cpuidExtData[8, 2] & 0xFF) + 1;
|
||||
|
||||
try {
|
||||
totalLoadCounter = new PerformanceCounter();
|
||||
totalLoadCounter.CategoryName = "Processor";
|
||||
totalLoadCounter.CounterName = "% Processor Time";
|
||||
totalLoadCounter.InstanceName = "_Total";
|
||||
totalLoadCounter.NextValue();
|
||||
} catch (Exception) {
|
||||
totalLoadCounter = null;
|
||||
}
|
||||
totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
|
||||
|
||||
coreLoadCounters = new PerformanceCounter[coreCount];
|
||||
coreLoads = new Sensor[coreCount];
|
||||
for (int i = 0; i < coreLoadCounters.Length; i++) {
|
||||
try {
|
||||
coreLoadCounters[i] = new PerformanceCounter();
|
||||
coreLoadCounters[i].CategoryName = "Processor";
|
||||
coreLoadCounters[i].CounterName = "% Processor Time";
|
||||
coreLoadCounters[i].InstanceName = i.ToString();
|
||||
coreLoadCounters[i].NextValue();
|
||||
} catch (Exception) {
|
||||
coreLoadCounters[i] = null;
|
||||
}
|
||||
for (int i = 0; i < coreCount; i++)
|
||||
coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1,
|
||||
SensorType.Load, this);
|
||||
}
|
||||
|
||||
cpuLoad = new CPULoad(coreCount, 1);
|
||||
if (cpuLoad.IsAvailable) {
|
||||
foreach (Sensor sensor in coreLoads)
|
||||
ActivateSensor(sensor);
|
||||
ActivateSensor(totalLoad);
|
||||
}
|
||||
|
||||
// AMD family 10h processors support only one temperature sensor
|
||||
coreTemperature = new Sensor(
|
||||
@@ -142,16 +128,12 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
DeactivateSensor(coreTemperature);
|
||||
}
|
||||
|
||||
if (totalLoadCounter != null) {
|
||||
totalLoad.Value = totalLoadCounter.NextValue();
|
||||
ActivateSensor(totalLoad);
|
||||
if (cpuLoad.IsAvailable) {
|
||||
cpuLoad.Update();
|
||||
for (int i = 0; i < coreLoads.Length; i++)
|
||||
coreLoads[i].Value = cpuLoad.GetCoreLoad(i);
|
||||
totalLoad.Value = cpuLoad.GetTotalLoad();
|
||||
}
|
||||
|
||||
for (int i = 0; i < coreLoads.Length; i++)
|
||||
if (coreLoadCounters[i] != null) {
|
||||
coreLoads[i].Value = coreLoadCounters[i].NextValue();
|
||||
ActivateSensor(coreLoads[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void ActivateSensor(Sensor sensor) {
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
|
||||
Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
|
||||
The contents of this file are subject to the Mozilla Public License Version
|
||||
1.1 (the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS" basis,
|
||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
for the specific language governing rights and limitations under the License.
|
||||
|
||||
The Original Code is the Open Hardware Monitor code.
|
||||
|
||||
The Initial Developer of the Original Code is
|
||||
Michael Möller <m.moeller@gmx.ch>.
|
||||
Portions created by the Initial Developer are Copyright (C) 2009-2010
|
||||
the Initial Developer. All Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms of
|
||||
either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
of those above. If you wish to allow use of your version of this file only
|
||||
under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
use your version of this file under the terms of the MPL, indicate your
|
||||
decision by deleting the provisions above and replace them with the notice
|
||||
and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file under
|
||||
the terms of any one of the MPL, the GPL or the LGPL.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
public class CPULoad {
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct SystemProcessorPerformanceInformation {
|
||||
public long IdleTime;
|
||||
public long KernelTime;
|
||||
public long UserTime;
|
||||
public long Reserved0;
|
||||
public long Reserved1;
|
||||
public ulong Reserved2;
|
||||
}
|
||||
|
||||
private enum SystemInformationClass : int {
|
||||
SystemBasicInformation = 0,
|
||||
SystemCpuInformation = 1,
|
||||
SystemPerformanceInformation = 2,
|
||||
SystemTimeOfDayInformation = 3,
|
||||
SystemProcessInformation = 5,
|
||||
SystemProcessorPerformanceInformation = 8
|
||||
}
|
||||
|
||||
[DllImport("ntdll.dll")]
|
||||
private static extern int NtQuerySystemInformation(
|
||||
SystemInformationClass informationClass,
|
||||
[Out] SystemProcessorPerformanceInformation[] informations,
|
||||
int structSize, out IntPtr returnLength);
|
||||
|
||||
private uint coreCount;
|
||||
private uint logicalProcessorsPerCore;
|
||||
|
||||
private long systemTime;
|
||||
private long[] idleTimes;
|
||||
|
||||
private float totalLoad;
|
||||
private float[] coreLoads;
|
||||
|
||||
private bool available = false;
|
||||
|
||||
private long[] GetIdleTimes() {
|
||||
long[] result = new long[coreCount * logicalProcessorsPerCore];
|
||||
SystemProcessorPerformanceInformation[] informations = new
|
||||
SystemProcessorPerformanceInformation[result.Length];
|
||||
|
||||
IntPtr returnLength;
|
||||
NtQuerySystemInformation(
|
||||
SystemInformationClass.SystemProcessorPerformanceInformation,
|
||||
informations, informations.Length *
|
||||
Marshal.SizeOf(typeof(SystemProcessorPerformanceInformation)),
|
||||
out returnLength);
|
||||
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
result[i] = informations[i].IdleTime;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public CPULoad(uint coreCount, uint logicalProcessorsPerCore) {
|
||||
this.coreCount = coreCount;
|
||||
this.logicalProcessorsPerCore = logicalProcessorsPerCore;
|
||||
this.coreLoads = new float[coreCount];
|
||||
this.systemTime = DateTime.Now.Ticks;
|
||||
this.totalLoad = 0;
|
||||
try {
|
||||
this.idleTimes = GetIdleTimes();
|
||||
} catch (Exception) {
|
||||
this.idleTimes = null;
|
||||
}
|
||||
if (idleTimes != null)
|
||||
available = true;
|
||||
}
|
||||
|
||||
public bool IsAvailable {
|
||||
get { return available; }
|
||||
}
|
||||
|
||||
public float GetTotalLoad() {
|
||||
return totalLoad;
|
||||
}
|
||||
|
||||
public float GetCoreLoad(int core) {
|
||||
return coreLoads[core];
|
||||
}
|
||||
|
||||
public void Update() {
|
||||
if (this.idleTimes == null)
|
||||
return;
|
||||
|
||||
long systemTime = DateTime.Now.Ticks;
|
||||
long[] idleTimes = GetIdleTimes();
|
||||
|
||||
if (systemTime - this.systemTime < 10000)
|
||||
return;
|
||||
|
||||
float total = 0;
|
||||
for (int i = 0; i < coreCount; i++) {
|
||||
float value = 0;
|
||||
for (int j = 0; j < logicalProcessorsPerCore; j++) {
|
||||
long index = i * logicalProcessorsPerCore + j;
|
||||
long delta = idleTimes[index] - this.idleTimes[index];
|
||||
value += delta;
|
||||
total += delta;
|
||||
}
|
||||
value = 1.0f - value / (logicalProcessorsPerCore *
|
||||
(systemTime - this.systemTime));
|
||||
value = value < 0 ? 0 : value;
|
||||
coreLoads[i] = value * 100;
|
||||
}
|
||||
total = 1.0f - total / (coreCount * logicalProcessorsPerCore *
|
||||
(systemTime - this.systemTime));
|
||||
total = total < 0 ? 0 : total;
|
||||
this.totalLoad = total * 100;
|
||||
|
||||
this.systemTime = systemTime;
|
||||
this.idleTimes = idleTimes;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+15
-48
@@ -59,9 +59,8 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
private uint logicalProcessorsPerCore;
|
||||
private uint coreCount;
|
||||
|
||||
private PerformanceCounter totalLoadCounter;
|
||||
private PerformanceCounter[] coreLoadCounters;
|
||||
|
||||
private CPULoad cpuLoad;
|
||||
|
||||
private const uint IA32_THERM_STATUS_MSR = 0x019C;
|
||||
private const uint IA32_TEMPERATURE_TARGET = 0x01A2;
|
||||
|
||||
@@ -133,30 +132,7 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
default: tjMax = 100; break;
|
||||
}
|
||||
|
||||
try {
|
||||
totalLoadCounter = new PerformanceCounter();
|
||||
totalLoadCounter.CategoryName = "Processor";
|
||||
totalLoadCounter.CounterName = "% Processor Time";
|
||||
totalLoadCounter.InstanceName = "_Total";
|
||||
totalLoadCounter.NextValue();
|
||||
} catch (Exception) {
|
||||
totalLoadCounter = null;
|
||||
}
|
||||
totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
|
||||
|
||||
coreLoadCounters = new PerformanceCounter[
|
||||
coreCount * logicalProcessorsPerCore];
|
||||
for (int i = 0; i < coreLoadCounters.Length; i++) {
|
||||
try {
|
||||
coreLoadCounters[i] = new PerformanceCounter();
|
||||
coreLoadCounters[i].CategoryName = "Processor";
|
||||
coreLoadCounters[i].CounterName = "% Processor Time";
|
||||
coreLoadCounters[i].InstanceName = i.ToString();
|
||||
coreLoadCounters[i].NextValue();
|
||||
} catch (Exception) {
|
||||
coreLoadCounters[i] = null;
|
||||
}
|
||||
}
|
||||
totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this);
|
||||
|
||||
coreTemperatures = new Sensor[coreCount];
|
||||
coreLoads = new Sensor[coreCount];
|
||||
@@ -167,6 +143,13 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
SensorType.Load, this);
|
||||
}
|
||||
|
||||
cpuLoad = new CPULoad(coreCount, logicalProcessorsPerCore);
|
||||
if (cpuLoad.IsAvailable) {
|
||||
foreach (Sensor sensor in coreLoads)
|
||||
ActivateSensor(sensor);
|
||||
ActivateSensor(totalLoad);
|
||||
}
|
||||
|
||||
Update();
|
||||
}
|
||||
|
||||
@@ -221,27 +204,11 @@ namespace OpenHardwareMonitor.Hardware.CPU {
|
||||
}
|
||||
}
|
||||
|
||||
if (totalLoadCounter != null) {
|
||||
totalLoad.Value = totalLoadCounter.NextValue();
|
||||
ActivateSensor(totalLoad);
|
||||
}
|
||||
|
||||
for (int i = 0; i < coreLoads.Length; i++) {
|
||||
float value = 0;
|
||||
int count = 0;
|
||||
for (int j = 0; j < logicalProcessorsPerCore; j++) {
|
||||
PerformanceCounter counter =
|
||||
coreLoadCounters[logicalProcessorsPerCore * i + j];
|
||||
if (counter != null) {
|
||||
value += counter.NextValue();
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count > 0) {
|
||||
value /= count;
|
||||
coreLoads[i].Value = value;
|
||||
ActivateSensor(coreLoads[i]);
|
||||
}
|
||||
if (cpuLoad.IsAvailable) {
|
||||
cpuLoad.Update();
|
||||
for (int i = 0; i < coreLoads.Length; i++)
|
||||
coreLoads[i].Value = cpuLoad.GetCoreLoad(i);
|
||||
totalLoad.Value = cpuLoad.GetTotalLoad();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
(ushort)(address + ADDRESS_REGISTER_OFFSET), register);
|
||||
return WinRing0.ReadIoPortByte(
|
||||
(ushort)(address + DATA_REGISTER_OFFSET));
|
||||
}
|
||||
}
|
||||
|
||||
public W83627DHG(Chip chip, byte revision, ushort address) {
|
||||
this.chip = chip;
|
||||
@@ -215,14 +215,14 @@ namespace OpenHardwareMonitor.Hardware.LPC {
|
||||
foreach (Sensor sensor in temperatures) {
|
||||
int value;
|
||||
if (sensor.Index < 2) {
|
||||
value = ReadByte((byte)(sensor.Index + 1), TEMPERATURE_BASE_REG);
|
||||
value = (sbyte)ReadByte((byte)(sensor.Index + 1), TEMPERATURE_BASE_REG);
|
||||
value = (value << 1) | ReadByte((byte)(sensor.Index + 1),
|
||||
(byte)(TEMPERATURE_BASE_REG + 1)) >> 7;
|
||||
} else {
|
||||
value = ReadByte(0, TEMPERATURE_SYS_REG) << 1;
|
||||
value = (sbyte)ReadByte(0, TEMPERATURE_SYS_REG) << 1;
|
||||
}
|
||||
sensor.Value = value / 2.0f;
|
||||
if (value < 0x1FE)
|
||||
if (value < 0xFE)
|
||||
ActivateSensor(sensor);
|
||||
else
|
||||
DeactivateSensor(sensor);
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<RootNamespace>OpenHardwareMonitor</RootNamespace>
|
||||
<ApplicationIcon>Resources\icon.ico</ApplicationIcon>
|
||||
<ApplicationManifest>Resources\app.manifest</ApplicationManifest>
|
||||
<StartupObject>OpenHardwareMonitor.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -59,6 +61,7 @@
|
||||
<Compile Include="GUI\TypeNode.cs" />
|
||||
<Compile Include="Hardware\CPU\AMD10CPU.cs" />
|
||||
<Compile Include="Hardware\CPU\AMD0FCPU.cs" />
|
||||
<Compile Include="Hardware\CPU\CPULoad.cs" />
|
||||
<Compile Include="Hardware\HDD\HDD.cs" />
|
||||
<Compile Include="Hardware\HDD\HDDGroup.cs" />
|
||||
<Compile Include="Hardware\HDD\SMART.cs" />
|
||||
@@ -139,6 +142,9 @@
|
||||
<EmbeddedResource Include="Resources\voltage.png" />
|
||||
<EmbeddedResource Include="Resources\nvidia.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\app.manifest" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio AllowExistingFolder="true" />
|
||||
|
||||
@@ -69,5 +69,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.1.12.0")]
|
||||
[assembly: AssemblyFileVersion("0.1.12.0")]
|
||||
[assembly: AssemblyVersion("0.1.13.0")]
|
||||
[assembly: AssemblyFileVersion("0.1.13.0")]
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
</asmv1:assembly>
|
||||
@@ -47,8 +47,9 @@ namespace OpenHardwareMonitor.Utilities {
|
||||
public HexStringArray(string input) {
|
||||
List<byte> list = new List<byte>();
|
||||
foreach (string str in input.Split(' ')) {
|
||||
if (str.Trim().Length > 0)
|
||||
list.Add(Convert.ToByte(str, 16));
|
||||
string s = str.Trim();
|
||||
if (s.Length > 0)
|
||||
list.Add(Convert.ToByte(s, 16));
|
||||
}
|
||||
array = list.ToArray();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user