Hardware/CPU/CPUGroup.cs
author moel.mich
Sun, 23 Sep 2012 18:37:43 +0000
changeset 380 573f1fff48b2
parent 301 d14ce71cef44
child 407 c9dfdbd59bf8
permissions -rw-r--r--
Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
     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 }