Fixed Issue 651.
3 This Source Code Form is subject to the terms of the Mozilla Public
4 License, v. 2.0. If a copy of the MPL was not distributed with this
5 file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 Copyright (C) 2009-2014 Michael Möller <mmoeller@openhardwaremonitor.org>
12 using System.Collections.Generic;
13 using System.Globalization;
16 namespace OpenHardwareMonitor.Hardware.CPU {
18 internal class CPUGroup : IGroup {
19 private readonly List<GenericCPU> hardware = new List<GenericCPU>();
21 private readonly CPUID[][][] threads;
23 private static CPUID[][] GetProcessorThreads() {
25 List<CPUID> threads = new List<CPUID>();
26 for (int i = 0; i < 64; i++) {
28 threads.Add(new CPUID(i));
29 } catch (ArgumentOutOfRangeException) { }
32 SortedDictionary<uint, List<CPUID>> processors =
33 new SortedDictionary<uint, List<CPUID>>();
34 foreach (CPUID thread in threads) {
36 processors.TryGetValue(thread.ProcessorId, out list);
38 list = new List<CPUID>();
39 processors.Add(thread.ProcessorId, list);
44 CPUID[][] processorThreads = new CPUID[processors.Count][];
46 foreach (List<CPUID> list in processors.Values) {
47 processorThreads[index] = list.ToArray();
50 return processorThreads;
53 private static CPUID[][] GroupThreadsByCore(IEnumerable<CPUID> threads) {
55 SortedDictionary<uint, List<CPUID>> cores =
56 new SortedDictionary<uint, List<CPUID>>();
57 foreach (CPUID thread in threads) {
59 cores.TryGetValue(thread.CoreId, out coreList);
60 if (coreList == null) {
61 coreList = new List<CPUID>();
62 cores.Add(thread.CoreId, coreList);
67 CPUID[][] coreThreads = new CPUID[cores.Count][];
69 foreach (List<CPUID> list in cores.Values) {
70 coreThreads[index] = list.ToArray();
76 public CPUGroup(ISettings settings) {
78 CPUID[][] processorThreads = GetProcessorThreads();
79 this.threads = new CPUID[processorThreads.Length][][];
82 foreach (CPUID[] threads in processorThreads) {
83 if (threads.Length == 0)
86 CPUID[][] coreThreads = GroupThreadsByCore(threads);
88 this.threads[index] = coreThreads;
90 switch (threads[0].Vendor) {
92 hardware.Add(new IntelCPU(index, coreThreads, settings));
95 switch (threads[0].Family) {
97 hardware.Add(new AMD0FCPU(index, coreThreads, settings));
105 hardware.Add(new AMD10CPU(index, coreThreads, settings));
108 hardware.Add(new GenericCPU(index, coreThreads, settings));
112 hardware.Add(new GenericCPU(index, coreThreads, settings));
120 public IHardware[] Hardware {
122 return hardware.ToArray();
126 private static void AppendCpuidData(StringBuilder r, uint[,] data,
129 for (int i = 0; i < data.GetLength(0); i++) {
131 r.Append((i + offset).ToString("X8", CultureInfo.InvariantCulture));
132 for (int j = 0; j < 4; j++) {
134 r.Append(data[i, j].ToString("X8", CultureInfo.InvariantCulture));
140 public string GetReport() {
144 StringBuilder r = new StringBuilder();
146 r.AppendLine("CPUID");
149 for (int i = 0; i < threads.Length; i++) {
151 r.AppendLine("Processor " + i);
153 r.AppendFormat("Processor Vendor: {0}{1}", threads[i][0][0].Vendor,
154 Environment.NewLine);
155 r.AppendFormat("Processor Brand: {0}{1}", threads[i][0][0].BrandString,
156 Environment.NewLine);
157 r.AppendFormat("Family: 0x{0}{1}",
158 threads[i][0][0].Family.ToString("X", CultureInfo.InvariantCulture),
159 Environment.NewLine);
160 r.AppendFormat("Model: 0x{0}{1}",
161 threads[i][0][0].Model.ToString("X", CultureInfo.InvariantCulture),
162 Environment.NewLine);
163 r.AppendFormat("Stepping: 0x{0}{1}",
164 threads[i][0][0].Stepping.ToString("X", CultureInfo.InvariantCulture),
165 Environment.NewLine);
168 r.AppendLine("CPUID Return Values");
170 for (int j = 0; j < threads[i].Length; j++)
171 for (int k = 0; k < threads[i][j].Length; k++) {
172 r.AppendLine(" CPU Thread: " + threads[i][j][k].Thread);
173 r.AppendLine(" APIC ID: " + threads[i][j][k].ApicId);
174 r.AppendLine(" Processor ID: " + threads[i][j][k].ProcessorId);
175 r.AppendLine(" Core ID: " + threads[i][j][k].CoreId);
176 r.AppendLine(" Thread ID: " + threads[i][j][k].ThreadId);
178 r.AppendLine(" Function EAX EBX ECX EDX");
179 AppendCpuidData(r, threads[i][j][k].Data, CPUID.CPUID_0);
180 AppendCpuidData(r, threads[i][j][k].ExtData, CPUID.CPUID_EXT);
187 public void Close() {
188 foreach (GenericCPU cpu in hardware) {