Hardware/CPU/CPULoad.cs
changeset 313 596df85bb4e1
parent 195 0ee888c485d5
child 344 3145aadca3d2
     1.1 --- a/Hardware/CPU/CPULoad.cs	Sun Jul 24 12:17:17 2011 +0000
     1.2 +++ b/Hardware/CPU/CPULoad.cs	Sun Jul 24 16:18:56 2011 +0000
     1.3 @@ -16,7 +16,7 @@
     1.4  
     1.5    The Initial Developer of the Original Code is 
     1.6    Michael Möller <m.moeller@gmx.ch>.
     1.7 -  Portions created by the Initial Developer are Copyright (C) 2009-2010
     1.8 +  Portions created by the Initial Developer are Copyright (C) 2009-2011
     1.9    the Initial Developer. All Rights Reserved.
    1.10  
    1.11    Contributor(s):
    1.12 @@ -62,43 +62,49 @@
    1.13  
    1.14      private readonly CPUID[][] cpuid;
    1.15  
    1.16 -    private long systemTime;
    1.17      private long[] idleTimes;
    1.18 +    private long[] totalTimes;
    1.19  
    1.20      private float totalLoad;
    1.21      private readonly float[] coreLoads;
    1.22  
    1.23      private readonly bool available;
    1.24  
    1.25 -    private static long[] GetIdleTimes() {      
    1.26 +    private static bool GetTimes(out long[] idle, out long[] total) {      
    1.27        SystemProcessorPerformanceInformation[] informations = new
    1.28          SystemProcessorPerformanceInformation[64];
    1.29  
    1.30        int size = Marshal.SizeOf(typeof(SystemProcessorPerformanceInformation));
    1.31  
    1.32 +      idle = null;
    1.33 +      total = null;
    1.34 +
    1.35        IntPtr returnLength;
    1.36        if (NativeMethods.NtQuerySystemInformation(
    1.37          SystemInformationClass.SystemProcessorPerformanceInformation,
    1.38          informations, informations.Length * size, out returnLength) != 0)
    1.39 -        return null;
    1.40 +        return false;
    1.41  
    1.42 -      long[] result = new long[(int)returnLength / size];
    1.43 +      idle = new long[(int)returnLength / size];
    1.44 +      total = new long[(int)returnLength / size];
    1.45  
    1.46 -      for (int i = 0; i < result.Length; i++)
    1.47 -        result[i] = informations[i].IdleTime;
    1.48 +      for (int i = 0; i < idle.Length; i++) {
    1.49 +        idle[i] = informations[i].IdleTime;
    1.50 +        total[i] = informations[i].KernelTime + informations[i].UserTime;
    1.51 +      }
    1.52  
    1.53 -      return result;
    1.54 +      return true;
    1.55      }
    1.56  
    1.57      public CPULoad(CPUID[][] cpuid) {
    1.58        this.cpuid = cpuid;
    1.59        this.coreLoads = new float[cpuid.Length];         
    1.60 -      this.systemTime = DateTime.Now.Ticks;
    1.61        this.totalLoad = 0;
    1.62        try {
    1.63 -        this.idleTimes = GetIdleTimes();
    1.64 +        GetTimes(out idleTimes, out totalTimes);
    1.65        } catch (Exception) {
    1.66          this.idleTimes = null;
    1.67 +        this.totalTimes = null;
    1.68        }
    1.69        if (idleTimes != null)
    1.70          available = true;
    1.71 @@ -120,13 +126,17 @@
    1.72        if (this.idleTimes == null)
    1.73          return;
    1.74  
    1.75 -      long newSystemTime = DateTime.Now.Ticks;
    1.76 -      long[] newIdleTimes = GetIdleTimes();
    1.77 +      long[] newIdleTimes;
    1.78 +      long[] newTotalTimes;
    1.79  
    1.80 -      if (newSystemTime - this.systemTime < 10000)
    1.81 +      if (!GetTimes(out newIdleTimes, out newTotalTimes))
    1.82          return;
    1.83  
    1.84 -      if (newIdleTimes == null)
    1.85 +      for (int i = 0; i < Math.Min(newTotalTimes.Length, totalTimes.Length); i++) 
    1.86 +        if (newTotalTimes[i] - this.totalTimes[i] < 100000)
    1.87 +          return;
    1.88 +
    1.89 +      if (newIdleTimes == null || newTotalTimes == null)
    1.90          return;
    1.91  
    1.92        float total = 0;
    1.93 @@ -135,27 +145,28 @@
    1.94          float value = 0;
    1.95          for (int j = 0; j < cpuid[i].Length; j++) {
    1.96            long index = cpuid[i][j].Thread;
    1.97 -          if (index < newIdleTimes.Length) {
    1.98 -            long delta = newIdleTimes[index] - this.idleTimes[index];
    1.99 -            value += delta;
   1.100 -            total += delta;
   1.101 +          if (index < newIdleTimes.Length && index < totalTimes.Length) {
   1.102 +            float idle = 
   1.103 +              (float)(newIdleTimes[index] - this.idleTimes[index]) /
   1.104 +              (float)(newTotalTimes[index] - this.totalTimes[index]);
   1.105 +            value += idle;
   1.106 +            total += idle;
   1.107              count++;
   1.108            }
   1.109          }
   1.110 -        value = 1.0f - value / (cpuid[i].Length * 
   1.111 -          (newSystemTime - this.systemTime));
   1.112 +        value = 1.0f - value / cpuid[i].Length;
   1.113          value = value < 0 ? 0 : value;
   1.114          coreLoads[i] = value * 100;
   1.115        }
   1.116        if (count > 0) {
   1.117 -        total = 1.0f - total / (count * (newSystemTime - this.systemTime));
   1.118 +        total = 1.0f - total / count;
   1.119          total = total < 0 ? 0 : total;
   1.120        } else {
   1.121          total = 0;
   1.122        }
   1.123        this.totalLoad = total * 100;
   1.124  
   1.125 -      this.systemTime = newSystemTime;
   1.126 +      this.totalTimes = newTotalTimes;
   1.127        this.idleTimes = newIdleTimes;
   1.128      }
   1.129