1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Hardware/CPU/CPULoad.cs Thu Feb 04 21:19:27 2010 +0000
1.3 @@ -0,0 +1,161 @@
1.4 +/*
1.5 +
1.6 + Version: MPL 1.1/GPL 2.0/LGPL 2.1
1.7 +
1.8 + The contents of this file are subject to the Mozilla Public License Version
1.9 + 1.1 (the "License"); you may not use this file except in compliance with
1.10 + the License. You may obtain a copy of the License at
1.11 +
1.12 + http://www.mozilla.org/MPL/
1.13 +
1.14 + Software distributed under the License is distributed on an "AS IS" basis,
1.15 + WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1.16 + for the specific language governing rights and limitations under the License.
1.17 +
1.18 + The Original Code is the Open Hardware Monitor code.
1.19 +
1.20 + The Initial Developer of the Original Code is
1.21 + Michael Möller <m.moeller@gmx.ch>.
1.22 + Portions created by the Initial Developer are Copyright (C) 2009-2010
1.23 + the Initial Developer. All Rights Reserved.
1.24 +
1.25 + Contributor(s):
1.26 +
1.27 + Alternatively, the contents of this file may be used under the terms of
1.28 + either the GNU General Public License Version 2 or later (the "GPL"), or
1.29 + the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
1.30 + in which case the provisions of the GPL or the LGPL are applicable instead
1.31 + of those above. If you wish to allow use of your version of this file only
1.32 + under the terms of either the GPL or the LGPL, and not to allow others to
1.33 + use your version of this file under the terms of the MPL, indicate your
1.34 + decision by deleting the provisions above and replace them with the notice
1.35 + and other provisions required by the GPL or the LGPL. If you do not delete
1.36 + the provisions above, a recipient may use your version of this file under
1.37 + the terms of any one of the MPL, the GPL or the LGPL.
1.38 +
1.39 +*/
1.40 +
1.41 +using System;
1.42 +using System.Collections.Generic;
1.43 +using System.Runtime.InteropServices;
1.44 +using System.Text;
1.45 +
1.46 +namespace OpenHardwareMonitor.Hardware.CPU {
1.47 + public class CPULoad {
1.48 +
1.49 + [StructLayout(LayoutKind.Sequential)]
1.50 + private struct SystemProcessorPerformanceInformation {
1.51 + public long IdleTime;
1.52 + public long KernelTime;
1.53 + public long UserTime;
1.54 + public long Reserved0;
1.55 + public long Reserved1;
1.56 + public ulong Reserved2;
1.57 + }
1.58 +
1.59 + private enum SystemInformationClass : int {
1.60 + SystemBasicInformation = 0,
1.61 + SystemCpuInformation = 1,
1.62 + SystemPerformanceInformation = 2,
1.63 + SystemTimeOfDayInformation = 3,
1.64 + SystemProcessInformation = 5,
1.65 + SystemProcessorPerformanceInformation = 8
1.66 + }
1.67 +
1.68 + [DllImport("ntdll.dll")]
1.69 + private static extern int NtQuerySystemInformation(
1.70 + SystemInformationClass informationClass,
1.71 + [Out] SystemProcessorPerformanceInformation[] informations,
1.72 + int structSize, out IntPtr returnLength);
1.73 +
1.74 + private uint coreCount;
1.75 + private uint logicalProcessorsPerCore;
1.76 +
1.77 + private long systemTime;
1.78 + private long[] idleTimes;
1.79 +
1.80 + private float totalLoad;
1.81 + private float[] coreLoads;
1.82 +
1.83 + private bool available = false;
1.84 +
1.85 + private long[] GetIdleTimes() {
1.86 + long[] result = new long[coreCount * logicalProcessorsPerCore];
1.87 + SystemProcessorPerformanceInformation[] informations = new
1.88 + SystemProcessorPerformanceInformation[result.Length];
1.89 +
1.90 + IntPtr returnLength;
1.91 + NtQuerySystemInformation(
1.92 + SystemInformationClass.SystemProcessorPerformanceInformation,
1.93 + informations, informations.Length *
1.94 + Marshal.SizeOf(typeof(SystemProcessorPerformanceInformation)),
1.95 + out returnLength);
1.96 +
1.97 + for (int i = 0; i < result.Length; i++)
1.98 + result[i] = informations[i].IdleTime;
1.99 +
1.100 + return result;
1.101 + }
1.102 +
1.103 + public CPULoad(uint coreCount, uint logicalProcessorsPerCore) {
1.104 + this.coreCount = coreCount;
1.105 + this.logicalProcessorsPerCore = logicalProcessorsPerCore;
1.106 + this.coreLoads = new float[coreCount];
1.107 + this.systemTime = DateTime.Now.Ticks;
1.108 + this.totalLoad = 0;
1.109 + try {
1.110 + this.idleTimes = GetIdleTimes();
1.111 + } catch (Exception) {
1.112 + this.idleTimes = null;
1.113 + }
1.114 + if (idleTimes != null)
1.115 + available = true;
1.116 + }
1.117 +
1.118 + public bool IsAvailable {
1.119 + get { return available; }
1.120 + }
1.121 +
1.122 + public float GetTotalLoad() {
1.123 + return totalLoad;
1.124 + }
1.125 +
1.126 + public float GetCoreLoad(int core) {
1.127 + return coreLoads[core];
1.128 + }
1.129 +
1.130 + public void Update() {
1.131 + if (this.idleTimes == null)
1.132 + return;
1.133 +
1.134 + long systemTime = DateTime.Now.Ticks;
1.135 + long[] idleTimes = GetIdleTimes();
1.136 +
1.137 + if (systemTime - this.systemTime < 10000)
1.138 + return;
1.139 +
1.140 + float total = 0;
1.141 + for (int i = 0; i < coreCount; i++) {
1.142 + float value = 0;
1.143 + for (int j = 0; j < logicalProcessorsPerCore; j++) {
1.144 + long index = i * logicalProcessorsPerCore + j;
1.145 + long delta = idleTimes[index] - this.idleTimes[index];
1.146 + value += delta;
1.147 + total += delta;
1.148 + }
1.149 + value = 1.0f - value / (logicalProcessorsPerCore *
1.150 + (systemTime - this.systemTime));
1.151 + value = value < 0 ? 0 : value;
1.152 + coreLoads[i] = value * 100;
1.153 + }
1.154 + total = 1.0f - total / (coreCount * logicalProcessorsPerCore *
1.155 + (systemTime - this.systemTime));
1.156 + total = total < 0 ? 0 : total;
1.157 + this.totalLoad = total * 100;
1.158 +
1.159 + this.systemTime = systemTime;
1.160 + this.idleTimes = idleTimes;
1.161 + }
1.162 +
1.163 + }
1.164 +}