moel@1: /* moel@1: moel@344: This Source Code Form is subject to the terms of the Mozilla Public moel@344: License, v. 2.0. If a copy of the MPL was not distributed with this moel@344: file, You can obtain one at http://mozilla.org/MPL/2.0/. moel@1: moel@427: Copyright (C) 2009-2014 Michael Möller moel@344: moel@1: */ moel@1: moel@1: using System; moel@1: using System.Collections.Generic; moel@166: using System.Globalization; moel@1: using System.Text; moel@1: moel@1: namespace OpenHardwareMonitor.Hardware.CPU { moel@1: moel@266: internal class CPUGroup : IGroup { moel@266: private readonly List hardware = new List(); moel@1: moel@195: private readonly CPUID[][][] threads; moel@1: moel@167: private static CPUID[][] GetProcessorThreads() { moel@1: moel@90: List threads = new List(); moel@427: for (int i = 0; i < 64; i++) { moel@90: try { moel@90: threads.Add(new CPUID(i)); moel@167: } catch (ArgumentOutOfRangeException) { } moel@90: } moel@1: moel@90: SortedDictionary> processors = moel@90: new SortedDictionary>(); moel@90: foreach (CPUID thread in threads) { moel@90: List list; moel@90: processors.TryGetValue(thread.ProcessorId, out list); moel@90: if (list == null) { moel@90: list = new List(); moel@90: processors.Add(thread.ProcessorId, list); moel@90: } moel@90: list.Add(thread); moel@90: } moel@90: moel@90: CPUID[][] processorThreads = new CPUID[processors.Count][]; moel@90: int index = 0; moel@90: foreach (List list in processors.Values) { moel@90: processorThreads[index] = list.ToArray(); moel@90: index++; moel@90: } moel@90: return processorThreads; moel@90: } moel@90: moel@195: private static CPUID[][] GroupThreadsByCore(IEnumerable threads) { moel@90: moel@90: SortedDictionary> cores = moel@90: new SortedDictionary>(); moel@90: foreach (CPUID thread in threads) { moel@90: List coreList; moel@90: cores.TryGetValue(thread.CoreId, out coreList); moel@90: if (coreList == null) { moel@90: coreList = new List(); moel@90: cores.Add(thread.CoreId, coreList); moel@90: } moel@90: coreList.Add(thread); moel@90: } moel@90: moel@90: CPUID[][] coreThreads = new CPUID[cores.Count][]; moel@90: int index = 0; moel@90: foreach (List list in cores.Values) { moel@90: coreThreads[index] = list.ToArray(); moel@90: index++; moel@90: } moel@90: return coreThreads; moel@1: } moel@1: moel@165: public CPUGroup(ISettings settings) { moel@1: moel@90: CPUID[][] processorThreads = GetProcessorThreads(); moel@90: this.threads = new CPUID[processorThreads.Length][][]; moel@1: moel@90: int index = 0; moel@90: foreach (CPUID[] threads in processorThreads) { moel@90: if (threads.Length == 0) moel@90: continue; moel@90: moel@90: CPUID[][] coreThreads = GroupThreadsByCore(threads); moel@1: moel@191: this.threads[index] = coreThreads; moel@1: moel@90: switch (threads[0].Vendor) { moel@90: case Vendor.Intel: moel@165: hardware.Add(new IntelCPU(index, coreThreads, settings)); moel@1: break; moel@90: case Vendor.AMD: moel@90: switch (threads[0].Family) { moel@90: case 0x0F: moel@165: hardware.Add(new AMD0FCPU(index, coreThreads, settings)); moel@90: break; moel@90: case 0x10: moel@251: case 0x11: moel@301: case 0x12: moel@271: case 0x14: moel@301: case 0x15: moel@407: case 0x16: moel@165: hardware.Add(new AMD10CPU(index, coreThreads, settings)); moel@90: break; moel@90: default: moel@191: hardware.Add(new GenericCPU(index, coreThreads, settings)); moel@90: break; moel@90: } break; moel@1: default: moel@191: hardware.Add(new GenericCPU(index, coreThreads, settings)); moel@1: break; moel@101: } moel@101: moel@101: index++; moel@1: } moel@1: } moel@90: moel@1: public IHardware[] Hardware { moel@1: get { moel@1: return hardware.ToArray(); moel@1: } moel@1: } moel@1: moel@167: private static void AppendCpuidData(StringBuilder r, uint[,] data, moel@167: uint offset) moel@167: { moel@1: for (int i = 0; i < data.GetLength(0); i++) { moel@1: r.Append(" "); moel@166: r.Append((i + offset).ToString("X8", CultureInfo.InvariantCulture)); moel@1: for (int j = 0; j < 4; j++) { moel@1: r.Append(" "); moel@166: r.Append(data[i, j].ToString("X8", CultureInfo.InvariantCulture)); moel@1: } moel@1: r.AppendLine(); moel@1: } moel@1: } moel@1: moel@1: public string GetReport() { moel@125: if (threads == null) moel@125: return null; moel@125: moel@1: StringBuilder r = new StringBuilder(); moel@90: moel@1: r.AppendLine("CPUID"); moel@1: r.AppendLine(); moel@1: moel@90: for (int i = 0; i < threads.Length; i++) { moel@1: moel@90: r.AppendLine("Processor " + i); moel@18: r.AppendLine(); moel@90: r.AppendFormat("Processor Vendor: {0}{1}", threads[i][0][0].Vendor, moel@90: Environment.NewLine); moel@90: r.AppendFormat("Processor Brand: {0}{1}", threads[i][0][0].BrandString, moel@90: Environment.NewLine); moel@90: r.AppendFormat("Family: 0x{0}{1}", moel@166: threads[i][0][0].Family.ToString("X", CultureInfo.InvariantCulture), moel@166: Environment.NewLine); moel@166: r.AppendFormat("Model: 0x{0}{1}", moel@166: threads[i][0][0].Model.ToString("X", CultureInfo.InvariantCulture), moel@166: Environment.NewLine); moel@166: r.AppendFormat("Stepping: 0x{0}{1}", moel@166: threads[i][0][0].Stepping.ToString("X", CultureInfo.InvariantCulture), moel@166: Environment.NewLine); moel@90: r.AppendLine(); moel@90: moel@90: r.AppendLine("CPUID Return Values"); moel@90: r.AppendLine(); moel@90: for (int j = 0; j < threads[i].Length; j++) moel@90: for (int k = 0; k < threads[i][j].Length; k++) { moel@90: r.AppendLine(" CPU Thread: " + threads[i][j][k].Thread); moel@90: r.AppendLine(" APIC ID: " + threads[i][j][k].ApicId); moel@90: r.AppendLine(" Processor ID: " + threads[i][j][k].ProcessorId); moel@90: r.AppendLine(" Core ID: " + threads[i][j][k].CoreId); moel@90: r.AppendLine(" Thread ID: " + threads[i][j][k].ThreadId); moel@90: r.AppendLine(); moel@90: r.AppendLine(" Function EAX EBX ECX EDX"); moel@90: AppendCpuidData(r, threads[i][j][k].Data, CPUID.CPUID_0); moel@90: AppendCpuidData(r, threads[i][j][k].ExtData, CPUID.CPUID_EXT); moel@90: r.AppendLine(); moel@90: } moel@18: } moel@90: return r.ToString(); moel@1: } moel@1: moel@266: public void Close() { moel@266: foreach (GenericCPU cpu in hardware) { moel@266: cpu.Close(); moel@266: } moel@266: } moel@1: } moel@1: }