# HG changeset patch # User moel.mich # Date 1285010905 0 # Node ID 6545fa3ae298e6f9c5b089a90be50cd75c4b5c9f # Parent d3a54e4077372e78ec9af7d06999958ac650ebab Refactored the CPU classes and added a GenericCPU class. diff -r d3a54e407737 -r 6545fa3ae298 Hardware/CPU/AMD0FCPU.cs --- a/Hardware/CPU/AMD0FCPU.cs Sat Sep 18 19:56:39 2010 +0000 +++ b/Hardware/CPU/AMD0FCPU.cs Mon Sep 20 19:28:25 2010 +0000 @@ -35,39 +35,21 @@ */ -using System; -using System.Globalization; +namespace OpenHardwareMonitor.Hardware.CPU { + internal sealed class AMD0FCPU : GenericCPU { -namespace OpenHardwareMonitor.Hardware.CPU { - internal sealed class AMD0FCPU : Hardware, IHardware { - - private string name; - - private int processorIndex; private uint pciAddress; - private Sensor[] coreTemperatures; - private Sensor totalLoad; - private Sensor[] coreLoads; - - private CPULoad cpuLoad; - private const ushort PCI_AMD_VENDOR_ID = 0x1022; private const ushort PCI_AMD_0FH_MISCELLANEOUS_DEVICE_ID = 0x1103; private const uint THERMTRIP_STATUS_REGISTER = 0xE4; private const byte THERM_SENSE_CORE_SEL_CPU0 = 0x4; private const byte THERM_SENSE_CORE_SEL_CPU1 = 0x0; - public AMD0FCPU(int processorIndex, CPUID[][] cpuid, ISettings settings) { - - this.processorIndex = processorIndex; - this.name = cpuid[0][0].Name; - - int coreCount = cpuid.Length; - - totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this, settings); - + public AMD0FCPU(int processorIndex, CPUID[][] cpuid, ISettings settings) + : base(processorIndex, cpuid, settings) + { float offset = -49.0f; // AM2+ 65nm +21 offset @@ -93,40 +75,19 @@ coreTemperatures = new Sensor[0]; } - coreLoads = new Sensor[coreCount]; - for (int i = 0; i < coreCount; i++) - coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1, - SensorType.Load, this, settings); - - cpuLoad = new CPULoad(cpuid); - 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, (byte)processorIndex); Update(); } - public override string Name { - get { return name; } - } - - public override Identifier Identifier { - get { - return new Identifier("amdcpu", - processorIndex.ToString(CultureInfo.InvariantCulture)); - } - } - - public override HardwareType HardwareType { - get { return HardwareType.CPU; } + protected override uint[] GetMSRs() { + return new uint[] { }; } public override void Update() { + base.Update(); + if (pciAddress != 0xFFFFFFFF) { for (uint i = 0; i < coreTemperatures.Length; i++) { if (WinRing0.WritePciConfigDwordEx( @@ -144,13 +105,7 @@ } } } - - if (cpuLoad.IsAvailable) { - cpuLoad.Update(); - for (int i = 0; i < coreLoads.Length; i++) - coreLoads[i].Value = cpuLoad.GetCoreLoad(i); - totalLoad.Value = cpuLoad.GetTotalLoad(); - } - } + } + } } diff -r d3a54e407737 -r 6545fa3ae298 Hardware/CPU/AMD10CPU.cs --- a/Hardware/CPU/AMD10CPU.cs Sat Sep 18 19:56:39 2010 +0000 +++ b/Hardware/CPU/AMD10CPU.cs Mon Sep 20 19:28:25 2010 +0000 @@ -35,52 +35,22 @@ */ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Diagnostics; -using System.Text; - namespace OpenHardwareMonitor.Hardware.CPU { - internal sealed class AMD10CPU : Hardware, IHardware { - private string name; + internal sealed class AMD10CPU : GenericCPU { - private int processorIndex; private uint pciAddress; private Sensor coreTemperature; - private Sensor totalLoad; - private Sensor[] coreLoads; - - private CPULoad cpuLoad; private const ushort PCI_AMD_VENDOR_ID = 0x1022; private const ushort PCI_AMD_10H_MISCELLANEOUS_DEVICE_ID = 0x1203; private const ushort PCI_AMD_11H_MISCELLANEOUS_DEVICE_ID = 0x1303; private const uint REPORTED_TEMPERATURE_CONTROL_REGISTER = 0xA4; - public AMD10CPU(int processorIndex, CPUID[][] cpuid, ISettings settings) { - - this.processorIndex = processorIndex; - this.name = cpuid[0][0].Name; - - int coreCount = cpuid.Length; - - totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this, settings); - - coreLoads = new Sensor[coreCount]; - for (int i = 0; i < coreCount; i++) - coreLoads[i] = new Sensor("Core #" + (i + 1), i + 1, - SensorType.Load, this, settings); - - cpuLoad = new CPULoad(cpuid); - if (cpuLoad.IsAvailable) { - foreach (Sensor sensor in coreLoads) - ActivateSensor(sensor); - ActivateSensor(totalLoad); - } - + public AMD10CPU(int processorIndex, CPUID[][] cpuid, ISettings settings) + : base(processorIndex, cpuid, settings) + { // AMD family 10h processors support only one temperature sensor coreTemperature = new Sensor( "Core" + (coreCount > 1 ? " #1 - #" + coreCount : ""), 0, @@ -97,22 +67,13 @@ Update(); } - public override string Name { - get { return name; } - } - - public override Identifier Identifier { - get { - return new Identifier("amdcpu", - processorIndex.ToString(CultureInfo.InvariantCulture)); - } - } - - public override HardwareType HardwareType { - get { return HardwareType.CPU; } + protected override uint[] GetMSRs() { + return new uint[] { }; } public override void Update() { + base.Update(); + if (pciAddress != 0xFFFFFFFF) { uint value; if (WinRing0.ReadPciConfigDwordEx(pciAddress, @@ -124,13 +85,6 @@ DeactivateSensor(coreTemperature); } } - - if (cpuLoad.IsAvailable) { - cpuLoad.Update(); - for (int i = 0; i < coreLoads.Length; i++) - coreLoads[i].Value = cpuLoad.GetCoreLoad(i); - totalLoad.Value = cpuLoad.GetTotalLoad(); - } } } } diff -r d3a54e407737 -r 6545fa3ae298 Hardware/CPU/CPUGroup.cs --- a/Hardware/CPU/CPUGroup.cs Sat Sep 18 19:56:39 2010 +0000 +++ b/Hardware/CPU/CPUGroup.cs Mon Sep 20 19:28:25 2010 +0000 @@ -119,7 +119,7 @@ CPUID[][] coreThreads = GroupThreadsByCore(threads); - this.threads[index] = coreThreads; + this.threads[index] = coreThreads; switch (threads[0].Vendor) { case Vendor.Intel: @@ -134,9 +134,11 @@ hardware.Add(new AMD10CPU(index, coreThreads, settings)); break; default: + hardware.Add(new GenericCPU(index, coreThreads, settings)); break; } break; default: + hardware.Add(new GenericCPU(index, coreThreads, settings)); break; } diff -r d3a54e407737 -r 6545fa3ae298 Hardware/CPU/GenericCPU.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Hardware/CPU/GenericCPU.cs Mon Sep 20 19:28:25 2010 +0000 @@ -0,0 +1,273 @@ +/* + + 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 . + Portions created by the Initial Developer are Copyright (C) 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.Diagnostics; +using System.Globalization; +using System.Text; +using System.Threading; + +namespace OpenHardwareMonitor.Hardware.CPU { + internal class GenericCPU : Hardware, IHardware { + + protected readonly CPUID[][] cpuid; + + protected readonly uint family; + protected readonly uint model; + protected readonly uint stepping; + + protected readonly int processorIndex; + protected readonly int coreCount; + protected readonly string name; + + protected readonly bool hasTSC; + protected readonly bool invariantTSC; + + private ulong lastTimeStampCount; + private long lastTime; + private double maxClock; + private double estimatedMaxClock; + + private Vendor vendor; + + private readonly CPULoad cpuLoad; + private readonly Sensor totalLoad; + private readonly Sensor[] coreLoads; + + protected string CoreString(int i) { + if (coreCount == 1) + return "CPU Core"; + else + return "CPU Core #" + (i + 1); + } + + public GenericCPU(int processorIndex, CPUID[][] cpuid, ISettings settings) { + this.cpuid = cpuid; + + this.vendor = cpuid[0][0].Vendor; + + this.family = cpuid[0][0].Family; + this.model = cpuid[0][0].Model; + this.stepping = cpuid[0][0].Stepping; + + this.processorIndex = processorIndex; + this.coreCount = cpuid.Length; + this.name = cpuid[0][0].Name; + + // check if processor has TSC + if (cpuid[0][0].Data.GetLength(0) > 1 + && (cpuid[0][0].Data[1, 3] & 0x10) != 0) + hasTSC = true; + else + hasTSC = false; + + // check if processor supports invariant TSC + if (cpuid[0][0].ExtData.GetLength(0) > 7 + && (cpuid[0][0].ExtData[7, 3] & 0x100) != 0) + invariantTSC = true; + else + invariantTSC = false; + + if (coreCount > 1) + totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this, settings); + else + totalLoad = null; + coreLoads = new Sensor[coreCount]; + for (int i = 0; i < coreLoads.Length; i++) + coreLoads[i] = new Sensor(CoreString(i), i + 1, + SensorType.Load, this, settings); + cpuLoad = new CPULoad(cpuid); + if (cpuLoad.IsAvailable) { + foreach (Sensor sensor in coreLoads) + ActivateSensor(sensor); + if (totalLoad != null) + ActivateSensor(totalLoad); + } + + if (hasTSC) + estimatedMaxClock = EstimateMaxClock(); + else + estimatedMaxClock = 0; + maxClock = estimatedMaxClock; + + lastTimeStampCount = 0; + lastTime = 0; + } + + private double EstimateMaxClock() { + // preload the function + EstimateMaxClock(0); + EstimateMaxClock(0); + + // estimate the max clock in MHz + List estimatedMaxClocks = new List(3); + for (int i = 0; i < 3; i++) + estimatedMaxClocks.Add(1e-6 * EstimateMaxClock(0.025)); + estimatedMaxClocks.Sort(); + return estimatedMaxClocks[1]; + } + + private static double EstimateMaxClock(double timeWindow) { + long ticks = (long)(timeWindow * Stopwatch.Frequency); + uint lsbBegin, msbBegin, lsbEnd, msbEnd; + + Thread.BeginThreadAffinity(); + long timeBegin = Stopwatch.GetTimestamp() + + (long)Math.Ceiling(0.001 * ticks); + long timeEnd = timeBegin + ticks; + while (Stopwatch.GetTimestamp() < timeBegin) { } + WinRing0.Rdtsc(out lsbBegin, out msbBegin); + while (Stopwatch.GetTimestamp() < timeEnd) { } + WinRing0.Rdtsc(out lsbEnd, out msbEnd); + Thread.EndThreadAffinity(); + + ulong countBegin = ((ulong)msbBegin << 32) | lsbBegin; + ulong countEnd = ((ulong)msbEnd << 32) | lsbEnd; + + return (((double)(countEnd - countBegin)) * Stopwatch.Frequency) / + (timeEnd - timeBegin); + } + + private static void AppendMSRData(StringBuilder r, uint msr, int thread) { + uint eax, edx; + if (WinRing0.RdmsrTx(msr, out eax, out edx, (UIntPtr)(1L << thread))) { + r.Append(" "); + r.Append((msr).ToString("X8", CultureInfo.InvariantCulture)); + r.Append(" "); + r.Append((edx).ToString("X8", CultureInfo.InvariantCulture)); + r.Append(" "); + r.Append((eax).ToString("X8", CultureInfo.InvariantCulture)); + r.AppendLine(); + } + } + + protected virtual uint[] GetMSRs() { + return null; + } + + public override string GetReport() { + StringBuilder r = new StringBuilder(); + + switch (vendor) { + case Vendor.AMD: r.AppendLine("Intel CPU"); break; + case Vendor.Intel: r.AppendLine("Intel CPU"); break; + default: r.AppendLine("Generic CPU"); break; + } + + r.AppendLine(); + r.AppendFormat("Name: {0}{1}", name, Environment.NewLine); + r.AppendFormat("Number of Cores: {0}{1}", coreCount, + Environment.NewLine); + r.AppendFormat("Threads per Core: {0}{1}", cpuid[0].Length, + Environment.NewLine); + r.AppendLine("TSC: " + + (hasTSC ? (invariantTSC ? "Invariant" : "Not Invariant") : "None")); + r.AppendLine(string.Format(CultureInfo.InvariantCulture, + "Timer Frequency: {0} MHz", Stopwatch.Frequency * 1e-6)); + r.AppendLine(string.Format(CultureInfo.InvariantCulture, + "Max Clock: {0} MHz", Math.Round(maxClock * 100) * 0.01)); + r.AppendLine(); + + uint[] msrArray = GetMSRs(); + if (msrArray != null && msrArray.Length > 0) { + for (int i = 0; i < cpuid.Length; i++) { + r.AppendLine("MSR Core #" + (i + 1)); + r.AppendLine(); + r.AppendLine(" MSR EDX EAX"); + foreach (uint msr in msrArray) + AppendMSRData(r, msr, cpuid[i][0].Thread); + r.AppendLine(); + } + } + + return r.ToString(); + } + + public override Identifier Identifier { + get { + string s; + switch (vendor) { + case Vendor.AMD: s = "amdcpu"; break; + case Vendor.Intel: s = "intelcpu"; break; + default: s = "genericcpu"; break; + } + return new Identifier(s, + processorIndex.ToString(CultureInfo.InvariantCulture)); + } + } + + public override string Name { + get { return name; } + } + + public override HardwareType HardwareType { + get { return HardwareType.CPU; } + } + + protected double MaxClock { + get { return maxClock; } + } + + public override void Update() { + if (hasTSC) { + uint lsb, msb; + WinRing0.RdtscTx(out lsb, out msb, (UIntPtr)1); + long time = Stopwatch.GetTimestamp(); + ulong timeStampCount = ((ulong)msb << 32) | lsb; + double delta = ((double)(time - lastTime)) / Stopwatch.Frequency; + if (delta > 0.5) { + if (invariantTSC) + maxClock = (timeStampCount - lastTimeStampCount) / (1e6 * delta); + else + maxClock = estimatedMaxClock; + + lastTimeStampCount = timeStampCount; + lastTime = time; + } + } + + if (cpuLoad.IsAvailable) { + cpuLoad.Update(); + for (int i = 0; i < coreLoads.Length; i++) + coreLoads[i].Value = cpuLoad.GetCoreLoad(i); + if (totalLoad != null) + totalLoad.Value = cpuLoad.GetTotalLoad(); + } + } + } +} diff -r d3a54e407737 -r 6545fa3ae298 Hardware/CPU/IntelCPU.cs --- a/Hardware/CPU/IntelCPU.cs Sat Sep 18 19:56:39 2010 +0000 +++ b/Hardware/CPU/IntelCPU.cs Mon Sep 20 19:28:25 2010 +0000 @@ -37,52 +37,21 @@ using System; using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.Text; -using System.Threading; namespace OpenHardwareMonitor.Hardware.CPU { - internal sealed class IntelCPU : Hardware, IHardware { - - private int processorIndex; - private CPUID[][] cpuid; - private int coreCount; - - private string name; - - private uint family; - private uint model; - private uint stepping; + internal sealed class IntelCPU : GenericCPU { private Sensor[] coreTemperatures; + private Sensor[] coreClocks; + private Sensor busClock; - private Sensor totalLoad; - private Sensor[] coreLoads; - private Sensor[] coreClocks; - private Sensor busClock; - private bool hasTSC; - private bool invariantTSC; - private double estimatedMaxClock; + private uint maxNehalemMultiplier = 0; - private CPULoad cpuLoad; - - private ulong lastTimeStampCount; - private long lastTime; - private uint maxNehalemMultiplier = 0; - private const uint IA32_THERM_STATUS_MSR = 0x019C; private const uint IA32_TEMPERATURE_TARGET = 0x01A2; private const uint IA32_PERF_STATUS = 0x0198; private const uint MSR_PLATFORM_INFO = 0xCE; - private string CoreString(int i) { - if (coreCount == 1) - return "CPU Core"; - else - return "CPU Core #" + (i + 1); - } - private float[] Floats(float f) { float[] result = new float[coreCount]; for (int i = 0; i < coreCount; i++) @@ -90,17 +59,9 @@ return result; } - public IntelCPU(int processorIndex, CPUID[][] cpuid, ISettings settings) { - - this.processorIndex = processorIndex; - this.cpuid = cpuid; - this.coreCount = cpuid.Length; - this.name = cpuid[0][0].Name; - - this.family = cpuid[0][0].Family; - this.model = cpuid[0][0].Model; - this.stepping = cpuid[0][0].Stepping; - + public IntelCPU(int processorIndex, CPUID[][] cpuid, ISettings settings) + : base(processorIndex, cpuid, settings) + { float[] tjMax; switch (family) { case 0x06: { @@ -134,7 +95,7 @@ tjMax = Floats(100); break; default: tjMax = Floats(90); break; - } break; + } break; case 0x1A: // Intel Core i7 LGA1366 (45nm) case 0x1E: // Intel Core i5, i7 LGA1156 (45nm) case 0x25: // Intel Core i3, i5, i7 LGA1156 (32nm) @@ -143,8 +104,7 @@ tjMax = new float[coreCount]; for (int i = 0; i < coreCount; i++) { if (WinRing0.RdmsrTx(IA32_TEMPERATURE_TARGET, out eax, - out edx, (UIntPtr)(1L << cpuid[i][0].Thread))) - { + out edx, (UIntPtr)(1L << cpuid[i][0].Thread))) { tjMax[i] = (eax >> 16) & 0xFF; } else { tjMax[i] = 100; @@ -162,9 +122,8 @@ } // check if processor supports a digital thermal sensor - if (cpuid[0][0].Data.GetLength(0) > 6 && - (cpuid[0][0].Data[6, 0] & 1) != 0) - { + if (cpuid[0][0].Data.GetLength(0) > 6 && + (cpuid[0][0].Data[6, 0] & 1) != 0) { coreTemperatures = new Sensor[coreCount]; for (int i = 0; i < coreTemperatures.Length; i++) { coreTemperatures[i] = new Sensor(CoreString(i), i, @@ -181,50 +140,7 @@ coreTemperatures = new Sensor[0]; } - if (coreCount > 1) - totalLoad = new Sensor("CPU Total", 0, SensorType.Load, this, settings); - else - totalLoad = null; - coreLoads = new Sensor[coreCount]; - for (int i = 0; i < coreLoads.Length; i++) - coreLoads[i] = new Sensor(CoreString(i), i + 1, - SensorType.Load, this, settings); - cpuLoad = new CPULoad(cpuid); - if (cpuLoad.IsAvailable) { - foreach (Sensor sensor in coreLoads) - ActivateSensor(sensor); - if (totalLoad != null) - ActivateSensor(totalLoad); - } - - // check if processor has TSC - if (cpuid[0][0].Data.GetLength(0) > 1 - && (cpuid[0][0].Data[1, 3] & 0x10) != 0) - hasTSC = true; - else - hasTSC = false; - - // check if processor supports invariant TSC - if (cpuid[0][0].ExtData.GetLength(0) > 7 - && (cpuid[0][0].ExtData[7, 3] & 0x100) != 0) - invariantTSC = true; - else - invariantTSC = false; - - // preload the function - EstimateMaxClock(0); - EstimateMaxClock(0); - - // estimate the max clock in MHz - List estimatedMaxClocks = new List(3); - for (int i = 0; i < 3; i++) - estimatedMaxClocks.Add(1e-6 * EstimateMaxClock(0.025)); - estimatedMaxClocks.Sort(); - estimatedMaxClock = estimatedMaxClocks[1]; - - lastTimeStampCount = 0; - lastTime = 0; - busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings); + busClock = new Sensor("Bus Speed", 0, SensorType.Clock, this, settings); coreClocks = new Sensor[coreCount]; for (int i = 0; i < coreClocks.Length; i++) { coreClocks[i] = @@ -232,96 +148,26 @@ if (hasTSC) ActivateSensor(coreClocks[i]); } - - Update(); + + Update(); } - public override string Name { - get { return name; } + protected override uint[] GetMSRs() { + return new uint[] { + MSR_PLATFORM_INFO, + IA32_PERF_STATUS , + IA32_THERM_STATUS_MSR, + IA32_TEMPERATURE_TARGET + }; } - public override Identifier Identifier { - get { - return new Identifier("intelcpu", - processorIndex.ToString(CultureInfo.InvariantCulture)); - } - } + public override void Update() { + base.Update(); - public override HardwareType HardwareType { - get { return HardwareType.CPU; } - } - - private static void AppendMSRData(StringBuilder r, uint msr, int thread) { - uint eax, edx; - if (WinRing0.RdmsrTx(msr, out eax, out edx, (UIntPtr)(1L << thread))) { - r.Append(" "); - r.Append((msr).ToString("X8", CultureInfo.InvariantCulture)); - r.Append(" "); - r.Append((edx).ToString("X8", CultureInfo.InvariantCulture)); - r.Append(" "); - r.Append((eax).ToString("X8", CultureInfo.InvariantCulture)); - r.AppendLine(); - } - } - - public override string GetReport() { - StringBuilder r = new StringBuilder(); - - r.AppendLine("Intel CPU"); - r.AppendLine(); - r.AppendFormat("Name: {0}{1}", name, Environment.NewLine); - r.AppendFormat("Number of Cores: {0}{1}", coreCount, - Environment.NewLine); - r.AppendFormat("Threads per Core: {0}{1}", cpuid[0].Length, - Environment.NewLine); - r.AppendLine("TSC: " + - (hasTSC ? (invariantTSC ? "Invariant" : "Not Invariant") : "None")); - r.AppendLine(string.Format(CultureInfo.InvariantCulture, - "Timer Frequency: {0} MHz", Stopwatch.Frequency * 1e-6)); - r.AppendLine(string.Format(CultureInfo.InvariantCulture, - "Max Clock: {0} MHz", Math.Round(estimatedMaxClock * 100) * 0.01)); - r.AppendLine(); - - for (int i = 0; i < cpuid.Length; i++) { - r.AppendLine("MSR Core #" + (i + 1)); - r.AppendLine(); - r.AppendLine(" MSR EDX EAX"); - AppendMSRData(r, MSR_PLATFORM_INFO, cpuid[i][0].Thread); - AppendMSRData(r, IA32_PERF_STATUS, cpuid[i][0].Thread); - AppendMSRData(r, IA32_THERM_STATUS_MSR, cpuid[i][0].Thread); - AppendMSRData(r, IA32_TEMPERATURE_TARGET, cpuid[i][0].Thread); - r.AppendLine(); - } - - return r.ToString(); - } - - private static double EstimateMaxClock(double timeWindow) { - long ticks = (long)(timeWindow * Stopwatch.Frequency); - uint lsbBegin, msbBegin, lsbEnd, msbEnd; - - Thread.BeginThreadAffinity(); - long timeBegin = Stopwatch.GetTimestamp() + - (long)Math.Ceiling(0.001 * ticks); - long timeEnd = timeBegin + ticks; - while (Stopwatch.GetTimestamp() < timeBegin) { } - WinRing0.Rdtsc(out lsbBegin, out msbBegin); - while (Stopwatch.GetTimestamp() < timeEnd) { } - WinRing0.Rdtsc(out lsbEnd, out msbEnd); - Thread.EndThreadAffinity(); - - ulong countBegin = ((ulong)msbBegin << 32) | lsbBegin; - ulong countEnd = ((ulong)msbEnd << 32) | lsbEnd; - - return (((double)(countEnd - countBegin)) * Stopwatch.Frequency) / - (timeEnd - timeBegin); - } - - public override void Update() { for (int i = 0; i < coreTemperatures.Length; i++) { uint eax, edx; if (WinRing0.RdmsrTx( - IA32_THERM_STATUS_MSR, out eax, out edx, + IA32_THERM_STATUS_MSR, out eax, out edx, (UIntPtr)(1L << cpuid[i][0].Thread))) { // if reading is valid if ((eax & 0x80000000) != 0) { @@ -336,62 +182,39 @@ } } - if (cpuLoad.IsAvailable) { - cpuLoad.Update(); - for (int i = 0; i < coreLoads.Length; i++) - coreLoads[i].Value = cpuLoad.GetCoreLoad(i); - if (totalLoad != null) - totalLoad.Value = cpuLoad.GetTotalLoad(); - } - if (hasTSC) { - uint lsb, msb; - WinRing0.RdtscTx(out lsb, out msb, (UIntPtr)1); - long time = Stopwatch.GetTimestamp(); - ulong timeStampCount = ((ulong)msb << 32) | lsb; - double delta = ((double)(time - lastTime)) / Stopwatch.Frequency; - if (delta > 0.5) { - double maxClock; - if (invariantTSC) - maxClock = (timeStampCount - lastTimeStampCount) / (1e6 * delta); - else - maxClock = estimatedMaxClock; - - double newBusClock = 0; - uint eax, edx; - for (int i = 0; i < coreClocks.Length; i++) { - System.Threading.Thread.Sleep(1); - if (WinRing0.RdmsrTx(IA32_PERF_STATUS, out eax, out edx, - (UIntPtr)(1L << cpuid[i][0].Thread))) { - if (maxNehalemMultiplier > 0) { // Core i3, i5, i7 - uint nehalemMultiplier = eax & 0xff; - coreClocks[i].Value = - (float)(nehalemMultiplier * maxClock / maxNehalemMultiplier); - newBusClock = (float)(maxClock / maxNehalemMultiplier); - } else { // Core 2 - uint multiplier = (eax >> 8) & 0x1f; - uint maxMultiplier = (edx >> 8) & 0x1f; - // factor = multiplier * 2 to handle non integer multipliers - uint factor = (multiplier << 1) | ((eax >> 14) & 1); - uint maxFactor = (maxMultiplier << 1) | ((edx >> 14) & 1); - if (maxFactor > 0) { - coreClocks[i].Value = (float)(factor * maxClock / maxFactor); - newBusClock = (float)(2 * maxClock / maxFactor); - } + double newBusClock = 0; + uint eax, edx; + for (int i = 0; i < coreClocks.Length; i++) { + System.Threading.Thread.Sleep(1); + if (WinRing0.RdmsrTx(IA32_PERF_STATUS, out eax, out edx, + (UIntPtr)(1L << cpuid[i][0].Thread))) { + if (maxNehalemMultiplier > 0) { // Core i3, i5, i7 + uint nehalemMultiplier = eax & 0xff; + coreClocks[i].Value = + (float)(nehalemMultiplier * MaxClock / maxNehalemMultiplier); + newBusClock = (float)(MaxClock / maxNehalemMultiplier); + } else { // Core 2 + uint multiplier = (eax >> 8) & 0x1f; + uint maxMultiplier = (edx >> 8) & 0x1f; + // factor = multiplier * 2 to handle non integer multipliers + uint factor = (multiplier << 1) | ((eax >> 14) & 1); + uint maxFactor = (maxMultiplier << 1) | ((edx >> 14) & 1); + if (maxFactor > 0) { + coreClocks[i].Value = (float)(factor * MaxClock / maxFactor); + newBusClock = (float)(2 * MaxClock / maxFactor); } - } else { // Intel Pentium 4 - // if IA32_PERF_STATUS is not available, assume maxClock - coreClocks[i].Value = (float)maxClock; } - } - if (newBusClock > 0) { - this.busClock.Value = (float)newBusClock; - ActivateSensor(this.busClock); + } else { // Intel Pentium 4 + // if IA32_PERF_STATUS is not available, assume maxClock + coreClocks[i].Value = (float)MaxClock; } } - lastTimeStampCount = timeStampCount; - lastTime = time; + if (newBusClock > 0) { + this.busClock.Value = (float)newBusClock; + ActivateSensor(this.busClock); + } } } - } + } } diff -r d3a54e407737 -r 6545fa3ae298 OpenHardwareMonitorLib.csproj --- a/OpenHardwareMonitorLib.csproj Sat Sep 18 19:56:39 2010 +0000 +++ b/OpenHardwareMonitorLib.csproj Mon Sep 20 19:28:25 2010 +0000 @@ -61,6 +61,7 @@ +