Hardware/CPU/CPUGroup.cs
author sl
Sun, 03 Feb 2013 18:01:50 +0100
changeset 391 ca4c0e7ae75d
parent 301 d14ce71cef44
permissions -rw-r--r--
Converted project to VisualStudio 2012.
Adding SoundGraphDisplay and SensorFrontView classes.
They were respectively based on SystemTray and SensorNotifyIcon.
SoundGraphDisplay is now able to load iMONDisplay.dll providing it lives on your PATH.
Adding option to sensor context menu for adding it into FrontView.
     1 /*
     2  
     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/.
     6  
     7   Copyright (C) 2009-2011 Michael Möller <mmoeller@openhardwaremonitor.org>
     8 	
     9 */
    10 
    11 using System;
    12 using System.Collections.Generic;
    13 using System.Globalization;
    14 using System.Text;
    15 
    16 namespace OpenHardwareMonitor.Hardware.CPU {
    17 
    18   internal class CPUGroup : IGroup {
    19     private readonly List<GenericCPU> hardware = new List<GenericCPU>();
    20 
    21     private readonly CPUID[][][] threads;
    22 
    23     private static CPUID[][] GetProcessorThreads() {
    24 
    25       List<CPUID> threads = new List<CPUID>();
    26       for (int i = 0; i < 32; i++) {
    27         try {
    28           threads.Add(new CPUID(i));
    29         } catch (ArgumentOutOfRangeException) { }
    30       }
    31 
    32       SortedDictionary<uint, List<CPUID>> processors =
    33         new SortedDictionary<uint, List<CPUID>>();
    34       foreach (CPUID thread in threads) {
    35         List<CPUID> list;
    36         processors.TryGetValue(thread.ProcessorId, out list);
    37         if (list == null) {
    38           list = new List<CPUID>();
    39           processors.Add(thread.ProcessorId, list);
    40         }
    41         list.Add(thread);
    42       }
    43 
    44       CPUID[][] processorThreads = new CPUID[processors.Count][];
    45       int index = 0;
    46       foreach (List<CPUID> list in processors.Values) {
    47         processorThreads[index] = list.ToArray();
    48         index++;
    49       }
    50       return processorThreads;
    51     }
    52 
    53     private static CPUID[][] GroupThreadsByCore(IEnumerable<CPUID> threads) {
    54 
    55       SortedDictionary<uint, List<CPUID>> cores = 
    56         new SortedDictionary<uint, List<CPUID>>();
    57       foreach (CPUID thread in threads) {
    58         List<CPUID> coreList;
    59         cores.TryGetValue(thread.CoreId, out coreList);
    60         if (coreList == null) {
    61           coreList = new List<CPUID>();
    62           cores.Add(thread.CoreId, coreList);
    63         }
    64         coreList.Add(thread);
    65       }
    66 
    67       CPUID[][] coreThreads = new CPUID[cores.Count][];
    68       int index = 0;
    69       foreach (List<CPUID> list in cores.Values) {
    70         coreThreads[index] = list.ToArray();
    71         index++;
    72       }
    73       return coreThreads;
    74     }
    75 
    76     public CPUGroup(ISettings settings) {
    77 
    78       CPUID[][] processorThreads = GetProcessorThreads();
    79       this.threads = new CPUID[processorThreads.Length][][];
    80 
    81       int index = 0;
    82       foreach (CPUID[] threads in processorThreads) {
    83         if (threads.Length == 0)
    84           continue;
    85             
    86         CPUID[][] coreThreads = GroupThreadsByCore(threads);
    87 
    88         this.threads[index] = coreThreads;
    89 
    90         switch (threads[0].Vendor) {
    91           case Vendor.Intel:
    92             hardware.Add(new IntelCPU(index, coreThreads, settings));
    93             break;
    94           case Vendor.AMD:
    95             switch (threads[0].Family) {
    96               case 0x0F:
    97                 hardware.Add(new AMD0FCPU(index, coreThreads, settings));
    98                 break;
    99               case 0x10:
   100               case 0x11:
   101               case 0x12:
   102               case 0x14:
   103               case 0x15:
   104                 hardware.Add(new AMD10CPU(index, coreThreads, settings));
   105                 break;
   106               default:
   107                 hardware.Add(new GenericCPU(index, coreThreads, settings));
   108                 break;
   109             } break;
   110           default:
   111             hardware.Add(new GenericCPU(index, coreThreads, settings));
   112             break;
   113         }
   114 
   115         index++;
   116       }
   117     }
   118     
   119     public IHardware[] Hardware {
   120       get {
   121         return hardware.ToArray();
   122       }
   123     }
   124 
   125     private static void AppendCpuidData(StringBuilder r, uint[,] data, 
   126       uint offset) 
   127     {
   128       for (int i = 0; i < data.GetLength(0); i++) {
   129         r.Append(" ");
   130         r.Append((i + offset).ToString("X8", CultureInfo.InvariantCulture));
   131         for (int j = 0; j < 4; j++) {
   132           r.Append("  ");
   133           r.Append(data[i, j].ToString("X8", CultureInfo.InvariantCulture));
   134         }
   135         r.AppendLine();
   136       }
   137     }
   138 
   139     public string GetReport() {
   140       if (threads == null)
   141         return null;
   142       
   143       StringBuilder r = new StringBuilder();
   144       
   145       r.AppendLine("CPUID");
   146       r.AppendLine();
   147 
   148       for (int i = 0; i < threads.Length; i++) {
   149 
   150         r.AppendLine("Processor " + i);
   151         r.AppendLine();
   152         r.AppendFormat("Processor Vendor: {0}{1}", threads[i][0][0].Vendor,
   153           Environment.NewLine);
   154         r.AppendFormat("Processor Brand: {0}{1}", threads[i][0][0].BrandString,
   155           Environment.NewLine);
   156         r.AppendFormat("Family: 0x{0}{1}", 
   157           threads[i][0][0].Family.ToString("X", CultureInfo.InvariantCulture), 
   158           Environment.NewLine);
   159         r.AppendFormat("Model: 0x{0}{1}",
   160           threads[i][0][0].Model.ToString("X", CultureInfo.InvariantCulture), 
   161           Environment.NewLine);
   162         r.AppendFormat("Stepping: 0x{0}{1}",
   163           threads[i][0][0].Stepping.ToString("X", CultureInfo.InvariantCulture), 
   164           Environment.NewLine);
   165         r.AppendLine();
   166 
   167         r.AppendLine("CPUID Return Values");
   168         r.AppendLine();
   169         for (int j = 0; j < threads[i].Length; j++)
   170           for (int k = 0; k < threads[i][j].Length; k++) {
   171             r.AppendLine(" CPU Thread: " + threads[i][j][k].Thread);
   172             r.AppendLine(" APIC ID: " + threads[i][j][k].ApicId);
   173             r.AppendLine(" Processor ID: " + threads[i][j][k].ProcessorId);
   174             r.AppendLine(" Core ID: " + threads[i][j][k].CoreId);
   175             r.AppendLine(" Thread ID: " + threads[i][j][k].ThreadId);
   176             r.AppendLine();
   177             r.AppendLine(" Function  EAX       EBX       ECX       EDX");
   178             AppendCpuidData(r, threads[i][j][k].Data, CPUID.CPUID_0);
   179             AppendCpuidData(r, threads[i][j][k].ExtData, CPUID.CPUID_EXT);
   180             r.AppendLine();
   181           }
   182       }
   183       return r.ToString(); 
   184     }
   185 
   186     public void Close() {
   187       foreach (GenericCPU cpu in hardware) {
   188         cpu.Close();
   189       }
   190     }
   191   }
   192 }