Hardware/CPU/CPUGroup.cs
author moel.mich
Sun, 23 Sep 2012 18:37:43 +0000
changeset 380 573f1fff48b2
parent 301 d14ce71cef44
permissions -rw-r--r--
Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
moel@1
     1
/*
moel@1
     2
 
moel@344
     3
  This Source Code Form is subject to the terms of the Mozilla Public
moel@344
     4
  License, v. 2.0. If a copy of the MPL was not distributed with this
moel@344
     5
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
moel@1
     6
 
moel@344
     7
  Copyright (C) 2009-2011 Michael Möller <mmoeller@openhardwaremonitor.org>
moel@344
     8
	
moel@1
     9
*/
moel@1
    10
moel@1
    11
using System;
moel@1
    12
using System.Collections.Generic;
moel@166
    13
using System.Globalization;
moel@1
    14
using System.Text;
moel@1
    15
moel@1
    16
namespace OpenHardwareMonitor.Hardware.CPU {
moel@1
    17
moel@266
    18
  internal class CPUGroup : IGroup {
moel@266
    19
    private readonly List<GenericCPU> hardware = new List<GenericCPU>();
moel@1
    20
moel@195
    21
    private readonly CPUID[][][] threads;
moel@1
    22
moel@167
    23
    private static CPUID[][] GetProcessorThreads() {
moel@1
    24
moel@90
    25
      List<CPUID> threads = new List<CPUID>();
moel@90
    26
      for (int i = 0; i < 32; i++) {
moel@90
    27
        try {
moel@90
    28
          threads.Add(new CPUID(i));
moel@167
    29
        } catch (ArgumentOutOfRangeException) { }
moel@90
    30
      }
moel@1
    31
moel@90
    32
      SortedDictionary<uint, List<CPUID>> processors =
moel@90
    33
        new SortedDictionary<uint, List<CPUID>>();
moel@90
    34
      foreach (CPUID thread in threads) {
moel@90
    35
        List<CPUID> list;
moel@90
    36
        processors.TryGetValue(thread.ProcessorId, out list);
moel@90
    37
        if (list == null) {
moel@90
    38
          list = new List<CPUID>();
moel@90
    39
          processors.Add(thread.ProcessorId, list);
moel@90
    40
        }
moel@90
    41
        list.Add(thread);
moel@90
    42
      }
moel@90
    43
moel@90
    44
      CPUID[][] processorThreads = new CPUID[processors.Count][];
moel@90
    45
      int index = 0;
moel@90
    46
      foreach (List<CPUID> list in processors.Values) {
moel@90
    47
        processorThreads[index] = list.ToArray();
moel@90
    48
        index++;
moel@90
    49
      }
moel@90
    50
      return processorThreads;
moel@90
    51
    }
moel@90
    52
moel@195
    53
    private static CPUID[][] GroupThreadsByCore(IEnumerable<CPUID> threads) {
moel@90
    54
moel@90
    55
      SortedDictionary<uint, List<CPUID>> cores = 
moel@90
    56
        new SortedDictionary<uint, List<CPUID>>();
moel@90
    57
      foreach (CPUID thread in threads) {
moel@90
    58
        List<CPUID> coreList;
moel@90
    59
        cores.TryGetValue(thread.CoreId, out coreList);
moel@90
    60
        if (coreList == null) {
moel@90
    61
          coreList = new List<CPUID>();
moel@90
    62
          cores.Add(thread.CoreId, coreList);
moel@90
    63
        }
moel@90
    64
        coreList.Add(thread);
moel@90
    65
      }
moel@90
    66
moel@90
    67
      CPUID[][] coreThreads = new CPUID[cores.Count][];
moel@90
    68
      int index = 0;
moel@90
    69
      foreach (List<CPUID> list in cores.Values) {
moel@90
    70
        coreThreads[index] = list.ToArray();
moel@90
    71
        index++;
moel@90
    72
      }
moel@90
    73
      return coreThreads;
moel@1
    74
    }
moel@1
    75
moel@165
    76
    public CPUGroup(ISettings settings) {
moel@1
    77
moel@90
    78
      CPUID[][] processorThreads = GetProcessorThreads();
moel@90
    79
      this.threads = new CPUID[processorThreads.Length][][];
moel@1
    80
moel@90
    81
      int index = 0;
moel@90
    82
      foreach (CPUID[] threads in processorThreads) {
moel@90
    83
        if (threads.Length == 0)
moel@90
    84
          continue;
moel@90
    85
            
moel@90
    86
        CPUID[][] coreThreads = GroupThreadsByCore(threads);
moel@1
    87
moel@191
    88
        this.threads[index] = coreThreads;
moel@1
    89
moel@90
    90
        switch (threads[0].Vendor) {
moel@90
    91
          case Vendor.Intel:
moel@165
    92
            hardware.Add(new IntelCPU(index, coreThreads, settings));
moel@1
    93
            break;
moel@90
    94
          case Vendor.AMD:
moel@90
    95
            switch (threads[0].Family) {
moel@90
    96
              case 0x0F:
moel@165
    97
                hardware.Add(new AMD0FCPU(index, coreThreads, settings));
moel@90
    98
                break;
moel@90
    99
              case 0x10:
moel@251
   100
              case 0x11:
moel@301
   101
              case 0x12:
moel@271
   102
              case 0x14:
moel@301
   103
              case 0x15:
moel@165
   104
                hardware.Add(new AMD10CPU(index, coreThreads, settings));
moel@90
   105
                break;
moel@90
   106
              default:
moel@191
   107
                hardware.Add(new GenericCPU(index, coreThreads, settings));
moel@90
   108
                break;
moel@90
   109
            } break;
moel@1
   110
          default:
moel@191
   111
            hardware.Add(new GenericCPU(index, coreThreads, settings));
moel@1
   112
            break;
moel@101
   113
        }
moel@101
   114
moel@101
   115
        index++;
moel@1
   116
      }
moel@1
   117
    }
moel@90
   118
    
moel@1
   119
    public IHardware[] Hardware {
moel@1
   120
      get {
moel@1
   121
        return hardware.ToArray();
moel@1
   122
      }
moel@1
   123
    }
moel@1
   124
moel@167
   125
    private static void AppendCpuidData(StringBuilder r, uint[,] data, 
moel@167
   126
      uint offset) 
moel@167
   127
    {
moel@1
   128
      for (int i = 0; i < data.GetLength(0); i++) {
moel@1
   129
        r.Append(" ");
moel@166
   130
        r.Append((i + offset).ToString("X8", CultureInfo.InvariantCulture));
moel@1
   131
        for (int j = 0; j < 4; j++) {
moel@1
   132
          r.Append("  ");
moel@166
   133
          r.Append(data[i, j].ToString("X8", CultureInfo.InvariantCulture));
moel@1
   134
        }
moel@1
   135
        r.AppendLine();
moel@1
   136
      }
moel@1
   137
    }
moel@1
   138
moel@1
   139
    public string GetReport() {
moel@125
   140
      if (threads == null)
moel@125
   141
        return null;
moel@125
   142
      
moel@1
   143
      StringBuilder r = new StringBuilder();
moel@90
   144
      
moel@1
   145
      r.AppendLine("CPUID");
moel@1
   146
      r.AppendLine();
moel@1
   147
moel@90
   148
      for (int i = 0; i < threads.Length; i++) {
moel@1
   149
moel@90
   150
        r.AppendLine("Processor " + i);
moel@18
   151
        r.AppendLine();
moel@90
   152
        r.AppendFormat("Processor Vendor: {0}{1}", threads[i][0][0].Vendor,
moel@90
   153
          Environment.NewLine);
moel@90
   154
        r.AppendFormat("Processor Brand: {0}{1}", threads[i][0][0].BrandString,
moel@90
   155
          Environment.NewLine);
moel@90
   156
        r.AppendFormat("Family: 0x{0}{1}", 
moel@166
   157
          threads[i][0][0].Family.ToString("X", CultureInfo.InvariantCulture), 
moel@166
   158
          Environment.NewLine);
moel@166
   159
        r.AppendFormat("Model: 0x{0}{1}",
moel@166
   160
          threads[i][0][0].Model.ToString("X", CultureInfo.InvariantCulture), 
moel@166
   161
          Environment.NewLine);
moel@166
   162
        r.AppendFormat("Stepping: 0x{0}{1}",
moel@166
   163
          threads[i][0][0].Stepping.ToString("X", CultureInfo.InvariantCulture), 
moel@166
   164
          Environment.NewLine);
moel@90
   165
        r.AppendLine();
moel@90
   166
moel@90
   167
        r.AppendLine("CPUID Return Values");
moel@90
   168
        r.AppendLine();
moel@90
   169
        for (int j = 0; j < threads[i].Length; j++)
moel@90
   170
          for (int k = 0; k < threads[i][j].Length; k++) {
moel@90
   171
            r.AppendLine(" CPU Thread: " + threads[i][j][k].Thread);
moel@90
   172
            r.AppendLine(" APIC ID: " + threads[i][j][k].ApicId);
moel@90
   173
            r.AppendLine(" Processor ID: " + threads[i][j][k].ProcessorId);
moel@90
   174
            r.AppendLine(" Core ID: " + threads[i][j][k].CoreId);
moel@90
   175
            r.AppendLine(" Thread ID: " + threads[i][j][k].ThreadId);
moel@90
   176
            r.AppendLine();
moel@90
   177
            r.AppendLine(" Function  EAX       EBX       ECX       EDX");
moel@90
   178
            AppendCpuidData(r, threads[i][j][k].Data, CPUID.CPUID_0);
moel@90
   179
            AppendCpuidData(r, threads[i][j][k].ExtData, CPUID.CPUID_EXT);
moel@90
   180
            r.AppendLine();
moel@90
   181
          }
moel@18
   182
      }
moel@90
   183
      return r.ToString(); 
moel@1
   184
    }
moel@1
   185
moel@266
   186
    public void Close() {
moel@266
   187
      foreach (GenericCPU cpu in hardware) {
moel@266
   188
        cpu.Close();
moel@266
   189
      }
moel@266
   190
    }
moel@1
   191
  }
moel@1
   192
}