Hardware/CPU/CPUGroup.cs
author moel.mich
Sat, 02 Oct 2010 18:15:46 +0000
changeset 206 1fa8eddc24a7
parent 191 6545fa3ae298
child 236 763675f19ff4
permissions -rw-r--r--
Replaced HttpUtility.UrlEncode with Uri.EscapeDataString and deleted the reference to the System.Web assembly. The System.Web assembly seems to be missing on some .NET 4.0 installations (and the overhead of using it is a bit large, just for the UrlEncode method).
moel@1
     1
/*
moel@1
     2
  
moel@1
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@1
     4
moel@1
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@1
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@1
     7
  the License. You may obtain a copy of the License at
moel@1
     8
 
moel@1
     9
  http://www.mozilla.org/MPL/
moel@1
    10
moel@1
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@1
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@1
    13
  for the specific language governing rights and limitations under the License.
moel@1
    14
moel@1
    15
  The Original Code is the Open Hardware Monitor code.
moel@1
    16
moel@1
    17
  The Initial Developer of the Original Code is 
moel@1
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@1
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@1
    20
  the Initial Developer. All Rights Reserved.
moel@1
    21
moel@1
    22
  Contributor(s):
moel@1
    23
moel@1
    24
  Alternatively, the contents of this file may be used under the terms of
moel@1
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@1
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@1
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@1
    28
  of those above. If you wish to allow use of your version of this file only
moel@1
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@1
    30
  use your version of this file under the terms of the MPL, indicate your
moel@1
    31
  decision by deleting the provisions above and replace them with the notice
moel@1
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@1
    33
  the provisions above, a recipient may use your version of this file under
moel@1
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@1
    35
 
moel@1
    36
*/
moel@1
    37
moel@1
    38
using System;
moel@1
    39
using System.Collections.Generic;
moel@166
    40
using System.Globalization;
moel@1
    41
using System.Text;
moel@1
    42
moel@1
    43
namespace OpenHardwareMonitor.Hardware.CPU {
moel@1
    44
moel@165
    45
  internal class CPUGroup : IGroup { 
moel@195
    46
    private readonly List<IHardware> hardware = new List<IHardware>();
moel@1
    47
moel@195
    48
    private readonly CPUID[][][] threads;
moel@1
    49
moel@167
    50
    private static CPUID[][] GetProcessorThreads() {
moel@1
    51
moel@90
    52
      List<CPUID> threads = new List<CPUID>();
moel@90
    53
      for (int i = 0; i < 32; i++) {
moel@90
    54
        try {
moel@90
    55
          threads.Add(new CPUID(i));
moel@167
    56
        } catch (ArgumentOutOfRangeException) { }
moel@90
    57
      }
moel@1
    58
moel@90
    59
      SortedDictionary<uint, List<CPUID>> processors =
moel@90
    60
        new SortedDictionary<uint, List<CPUID>>();
moel@90
    61
      foreach (CPUID thread in threads) {
moel@90
    62
        List<CPUID> list;
moel@90
    63
        processors.TryGetValue(thread.ProcessorId, out list);
moel@90
    64
        if (list == null) {
moel@90
    65
          list = new List<CPUID>();
moel@90
    66
          processors.Add(thread.ProcessorId, list);
moel@90
    67
        }
moel@90
    68
        list.Add(thread);
moel@90
    69
      }
moel@90
    70
moel@90
    71
      CPUID[][] processorThreads = new CPUID[processors.Count][];
moel@90
    72
      int index = 0;
moel@90
    73
      foreach (List<CPUID> list in processors.Values) {
moel@90
    74
        processorThreads[index] = list.ToArray();
moel@90
    75
        index++;
moel@90
    76
      }
moel@90
    77
      return processorThreads;
moel@90
    78
    }
moel@90
    79
moel@195
    80
    private static CPUID[][] GroupThreadsByCore(IEnumerable<CPUID> threads) {
moel@90
    81
moel@90
    82
      SortedDictionary<uint, List<CPUID>> cores = 
moel@90
    83
        new SortedDictionary<uint, List<CPUID>>();
moel@90
    84
      foreach (CPUID thread in threads) {
moel@90
    85
        List<CPUID> coreList;
moel@90
    86
        cores.TryGetValue(thread.CoreId, out coreList);
moel@90
    87
        if (coreList == null) {
moel@90
    88
          coreList = new List<CPUID>();
moel@90
    89
          cores.Add(thread.CoreId, coreList);
moel@90
    90
        }
moel@90
    91
        coreList.Add(thread);
moel@90
    92
      }
moel@90
    93
moel@90
    94
      CPUID[][] coreThreads = new CPUID[cores.Count][];
moel@90
    95
      int index = 0;
moel@90
    96
      foreach (List<CPUID> list in cores.Values) {
moel@90
    97
        coreThreads[index] = list.ToArray();
moel@90
    98
        index++;
moel@90
    99
      }
moel@90
   100
      return coreThreads;
moel@1
   101
    }
moel@1
   102
moel@165
   103
    public CPUGroup(ISettings settings) {
moel@125
   104
      // No implementation for cpuid on Unix systems
moel@195
   105
      int p = (int)Environment.OSVersion.Platform;
moel@125
   106
      if ((p == 4) || (p == 128)) 
moel@125
   107
        return;
moel@125
   108
      
moel@90
   109
      if (!WinRing0.IsCpuid())
moel@1
   110
        return;
moel@1
   111
moel@90
   112
      CPUID[][] processorThreads = GetProcessorThreads();
moel@90
   113
      this.threads = new CPUID[processorThreads.Length][][];
moel@1
   114
moel@90
   115
      int index = 0;
moel@90
   116
      foreach (CPUID[] threads in processorThreads) {
moel@90
   117
        if (threads.Length == 0)
moel@90
   118
          continue;
moel@90
   119
            
moel@90
   120
        CPUID[][] coreThreads = GroupThreadsByCore(threads);
moel@1
   121
moel@191
   122
        this.threads[index] = coreThreads;
moel@1
   123
moel@90
   124
        switch (threads[0].Vendor) {
moel@90
   125
          case Vendor.Intel:
moel@165
   126
            hardware.Add(new IntelCPU(index, coreThreads, settings));
moel@1
   127
            break;
moel@90
   128
          case Vendor.AMD:
moel@90
   129
            switch (threads[0].Family) {
moel@90
   130
              case 0x0F:
moel@165
   131
                hardware.Add(new AMD0FCPU(index, coreThreads, settings));
moel@90
   132
                break;
moel@90
   133
              case 0x10:
moel@165
   134
                hardware.Add(new AMD10CPU(index, coreThreads, settings));
moel@90
   135
                break;
moel@90
   136
              default:
moel@191
   137
                hardware.Add(new GenericCPU(index, coreThreads, settings));
moel@90
   138
                break;
moel@90
   139
            } break;
moel@1
   140
          default:
moel@191
   141
            hardware.Add(new GenericCPU(index, coreThreads, settings));
moel@1
   142
            break;
moel@101
   143
        }
moel@101
   144
moel@101
   145
        index++;
moel@1
   146
      }
moel@1
   147
    }
moel@90
   148
    
moel@1
   149
    public IHardware[] Hardware {
moel@1
   150
      get {
moel@1
   151
        return hardware.ToArray();
moel@1
   152
      }
moel@1
   153
    }
moel@1
   154
moel@167
   155
    private static void AppendCpuidData(StringBuilder r, uint[,] data, 
moel@167
   156
      uint offset) 
moel@167
   157
    {
moel@1
   158
      for (int i = 0; i < data.GetLength(0); i++) {
moel@1
   159
        r.Append(" ");
moel@166
   160
        r.Append((i + offset).ToString("X8", CultureInfo.InvariantCulture));
moel@1
   161
        for (int j = 0; j < 4; j++) {
moel@1
   162
          r.Append("  ");
moel@166
   163
          r.Append(data[i, j].ToString("X8", CultureInfo.InvariantCulture));
moel@1
   164
        }
moel@1
   165
        r.AppendLine();
moel@1
   166
      }
moel@1
   167
    }
moel@1
   168
moel@1
   169
    public string GetReport() {
moel@125
   170
      if (threads == null)
moel@125
   171
        return null;
moel@125
   172
      
moel@1
   173
      StringBuilder r = new StringBuilder();
moel@90
   174
      
moel@1
   175
      r.AppendLine("CPUID");
moel@1
   176
      r.AppendLine();
moel@1
   177
moel@90
   178
      for (int i = 0; i < threads.Length; i++) {
moel@1
   179
moel@90
   180
        r.AppendLine("Processor " + i);
moel@18
   181
        r.AppendLine();
moel@90
   182
        r.AppendFormat("Processor Vendor: {0}{1}", threads[i][0][0].Vendor,
moel@90
   183
          Environment.NewLine);
moel@90
   184
        r.AppendFormat("Processor Brand: {0}{1}", threads[i][0][0].BrandString,
moel@90
   185
          Environment.NewLine);
moel@90
   186
        r.AppendFormat("Family: 0x{0}{1}", 
moel@166
   187
          threads[i][0][0].Family.ToString("X", CultureInfo.InvariantCulture), 
moel@166
   188
          Environment.NewLine);
moel@166
   189
        r.AppendFormat("Model: 0x{0}{1}",
moel@166
   190
          threads[i][0][0].Model.ToString("X", CultureInfo.InvariantCulture), 
moel@166
   191
          Environment.NewLine);
moel@166
   192
        r.AppendFormat("Stepping: 0x{0}{1}",
moel@166
   193
          threads[i][0][0].Stepping.ToString("X", CultureInfo.InvariantCulture), 
moel@166
   194
          Environment.NewLine);
moel@90
   195
        r.AppendLine();
moel@90
   196
moel@90
   197
        r.AppendLine("CPUID Return Values");
moel@90
   198
        r.AppendLine();
moel@90
   199
        for (int j = 0; j < threads[i].Length; j++)
moel@90
   200
          for (int k = 0; k < threads[i][j].Length; k++) {
moel@90
   201
            r.AppendLine(" CPU Thread: " + threads[i][j][k].Thread);
moel@90
   202
            r.AppendLine(" APIC ID: " + threads[i][j][k].ApicId);
moel@90
   203
            r.AppendLine(" Processor ID: " + threads[i][j][k].ProcessorId);
moel@90
   204
            r.AppendLine(" Core ID: " + threads[i][j][k].CoreId);
moel@90
   205
            r.AppendLine(" Thread ID: " + threads[i][j][k].ThreadId);
moel@90
   206
            r.AppendLine();
moel@90
   207
            r.AppendLine(" Function  EAX       EBX       ECX       EDX");
moel@90
   208
            AppendCpuidData(r, threads[i][j][k].Data, CPUID.CPUID_0);
moel@90
   209
            AppendCpuidData(r, threads[i][j][k].ExtData, CPUID.CPUID_EXT);
moel@90
   210
            r.AppendLine();
moel@90
   211
          }
moel@18
   212
      }
moel@90
   213
      return r.ToString(); 
moel@1
   214
    }
moel@1
   215
moel@1
   216
    public void Close() { }
moel@1
   217
  }
moel@1
   218
}