Hardware/CPU/CPUGroup.cs
author moel.mich
Sat, 29 Jun 2013 16:12:40 +0000
changeset 407 c9dfdbd59bf8
parent 344 3145aadca3d2
child 427 39ed1a16c32a
permissions -rw-r--r--
Added experimental support for AMD family 15h model 1Xh and family 16h CPUs.
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@407
     7
  Copyright (C) 2009-2013 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@407
   104
              case 0x16:
moel@165
   105
                hardware.Add(new AMD10CPU(index, coreThreads, settings));
moel@90
   106
                break;
moel@90
   107
              default:
moel@191
   108
                hardware.Add(new GenericCPU(index, coreThreads, settings));
moel@90
   109
                break;
moel@90
   110
            } break;
moel@1
   111
          default:
moel@191
   112
            hardware.Add(new GenericCPU(index, coreThreads, settings));
moel@1
   113
            break;
moel@101
   114
        }
moel@101
   115
moel@101
   116
        index++;
moel@1
   117
      }
moel@1
   118
    }
moel@90
   119
    
moel@1
   120
    public IHardware[] Hardware {
moel@1
   121
      get {
moel@1
   122
        return hardware.ToArray();
moel@1
   123
      }
moel@1
   124
    }
moel@1
   125
moel@167
   126
    private static void AppendCpuidData(StringBuilder r, uint[,] data, 
moel@167
   127
      uint offset) 
moel@167
   128
    {
moel@1
   129
      for (int i = 0; i < data.GetLength(0); i++) {
moel@1
   130
        r.Append(" ");
moel@166
   131
        r.Append((i + offset).ToString("X8", CultureInfo.InvariantCulture));
moel@1
   132
        for (int j = 0; j < 4; j++) {
moel@1
   133
          r.Append("  ");
moel@166
   134
          r.Append(data[i, j].ToString("X8", CultureInfo.InvariantCulture));
moel@1
   135
        }
moel@1
   136
        r.AppendLine();
moel@1
   137
      }
moel@1
   138
    }
moel@1
   139
moel@1
   140
    public string GetReport() {
moel@125
   141
      if (threads == null)
moel@125
   142
        return null;
moel@125
   143
      
moel@1
   144
      StringBuilder r = new StringBuilder();
moel@90
   145
      
moel@1
   146
      r.AppendLine("CPUID");
moel@1
   147
      r.AppendLine();
moel@1
   148
moel@90
   149
      for (int i = 0; i < threads.Length; i++) {
moel@1
   150
moel@90
   151
        r.AppendLine("Processor " + i);
moel@18
   152
        r.AppendLine();
moel@90
   153
        r.AppendFormat("Processor Vendor: {0}{1}", threads[i][0][0].Vendor,
moel@90
   154
          Environment.NewLine);
moel@90
   155
        r.AppendFormat("Processor Brand: {0}{1}", threads[i][0][0].BrandString,
moel@90
   156
          Environment.NewLine);
moel@90
   157
        r.AppendFormat("Family: 0x{0}{1}", 
moel@166
   158
          threads[i][0][0].Family.ToString("X", CultureInfo.InvariantCulture), 
moel@166
   159
          Environment.NewLine);
moel@166
   160
        r.AppendFormat("Model: 0x{0}{1}",
moel@166
   161
          threads[i][0][0].Model.ToString("X", CultureInfo.InvariantCulture), 
moel@166
   162
          Environment.NewLine);
moel@166
   163
        r.AppendFormat("Stepping: 0x{0}{1}",
moel@166
   164
          threads[i][0][0].Stepping.ToString("X", CultureInfo.InvariantCulture), 
moel@166
   165
          Environment.NewLine);
moel@90
   166
        r.AppendLine();
moel@90
   167
moel@90
   168
        r.AppendLine("CPUID Return Values");
moel@90
   169
        r.AppendLine();
moel@90
   170
        for (int j = 0; j < threads[i].Length; j++)
moel@90
   171
          for (int k = 0; k < threads[i][j].Length; k++) {
moel@90
   172
            r.AppendLine(" CPU Thread: " + threads[i][j][k].Thread);
moel@90
   173
            r.AppendLine(" APIC ID: " + threads[i][j][k].ApicId);
moel@90
   174
            r.AppendLine(" Processor ID: " + threads[i][j][k].ProcessorId);
moel@90
   175
            r.AppendLine(" Core ID: " + threads[i][j][k].CoreId);
moel@90
   176
            r.AppendLine(" Thread ID: " + threads[i][j][k].ThreadId);
moel@90
   177
            r.AppendLine();
moel@90
   178
            r.AppendLine(" Function  EAX       EBX       ECX       EDX");
moel@90
   179
            AppendCpuidData(r, threads[i][j][k].Data, CPUID.CPUID_0);
moel@90
   180
            AppendCpuidData(r, threads[i][j][k].ExtData, CPUID.CPUID_EXT);
moel@90
   181
            r.AppendLine();
moel@90
   182
          }
moel@18
   183
      }
moel@90
   184
      return r.ToString(); 
moel@1
   185
    }
moel@1
   186
moel@266
   187
    public void Close() {
moel@266
   188
      foreach (GenericCPU cpu in hardware) {
moel@266
   189
        cpu.Close();
moel@266
   190
      }
moel@266
   191
    }
moel@1
   192
  }
moel@1
   193
}