Hardware/CPU/CPULoad.cs
changeset 26 0e01b63e1fdc
child 90 3333b29a1746
     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 +}