Hardware/CPU/CPUGroup.cs
author StephaneLenclud
Thu, 18 Apr 2013 23:25:10 +0200
branchMiniDisplay
changeset 444 9b09e2ee0968
parent 407 c9dfdbd59bf8
permissions -rw-r--r--
Front View plug-in does not init if no sensor added.
Fixing some format to make strings shorter.
Now trying to start SoundGraphAccess.exe process from same directory.
Packed mode now can display three sensors along with the current time.
     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-2014 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 < 64; 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               case 0x16:
   105                 hardware.Add(new AMD10CPU(index, coreThreads, settings));
   106                 break;
   107               default:
   108                 hardware.Add(new GenericCPU(index, coreThreads, settings));
   109                 break;
   110             } break;
   111           default:
   112             hardware.Add(new GenericCPU(index, coreThreads, settings));
   113             break;
   114         }
   115 
   116         index++;
   117       }
   118     }
   119     
   120     public IHardware[] Hardware {
   121       get {
   122         return hardware.ToArray();
   123       }
   124     }
   125 
   126     private static void AppendCpuidData(StringBuilder r, uint[,] data, 
   127       uint offset) 
   128     {
   129       for (int i = 0; i < data.GetLength(0); i++) {
   130         r.Append(" ");
   131         r.Append((i + offset).ToString("X8", CultureInfo.InvariantCulture));
   132         for (int j = 0; j < 4; j++) {
   133           r.Append("  ");
   134           r.Append(data[i, j].ToString("X8", CultureInfo.InvariantCulture));
   135         }
   136         r.AppendLine();
   137       }
   138     }
   139 
   140     public string GetReport() {
   141       if (threads == null)
   142         return null;
   143       
   144       StringBuilder r = new StringBuilder();
   145       
   146       r.AppendLine("CPUID");
   147       r.AppendLine();
   148 
   149       for (int i = 0; i < threads.Length; i++) {
   150 
   151         r.AppendLine("Processor " + i);
   152         r.AppendLine();
   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);
   166         r.AppendLine();
   167 
   168         r.AppendLine("CPUID Return Values");
   169         r.AppendLine();
   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);
   177             r.AppendLine();
   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);
   181             r.AppendLine();
   182           }
   183       }
   184       return r.ToString(); 
   185     }
   186 
   187     public void Close() {
   188       foreach (GenericCPU cpu in hardware) {
   189         cpu.Close();
   190       }
   191     }
   192   }
   193 }