Hardware/CPU/CPUGroup.cs
author moel.mich
Thu, 11 Nov 2010 21:22:24 +0000
changeset 241 52007c404f32
parent 236 763675f19ff4
child 251 49c38a2958c8
permissions -rw-r--r--
Fixed a problem, where the MainForm location and size was lost when the application is started minimized and exited without ever showing the form. This caused MainForm_Load to be never called (location and size was not loaded), but the default size and location were still saved. The new implementation only saves the location and size when one of the two is changed.
moel@1
     1
/*
moel@1
     2
  
moel@1
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@1
     4
moel@1
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@1
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@1
     7
  the License. You may obtain a copy of the License at
moel@1
     8
 
moel@1
     9
  http://www.mozilla.org/MPL/
moel@1
    10
moel@1
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@1
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@1
    13
  for the specific language governing rights and limitations under the License.
moel@1
    14
moel@1
    15
  The Original Code is the Open Hardware Monitor code.
moel@1
    16
moel@1
    17
  The Initial Developer of the Original Code is 
moel@1
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@1
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@1
    20
  the Initial Developer. All Rights Reserved.
moel@1
    21
moel@1
    22
  Contributor(s):
moel@1
    23
moel@1
    24
  Alternatively, the contents of this file may be used under the terms of
moel@1
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@1
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@1
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@1
    28
  of those above. If you wish to allow use of your version of this file only
moel@1
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@1
    30
  use your version of this file under the terms of the MPL, indicate your
moel@1
    31
  decision by deleting the provisions above and replace them with the notice
moel@1
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@1
    33
  the provisions above, a recipient may use your version of this file under
moel@1
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@1
    35
 
moel@1
    36
*/
moel@1
    37
moel@1
    38
using System;
moel@1
    39
using System.Collections.Generic;
moel@166
    40
using System.Globalization;
moel@1
    41
using System.Text;
moel@1
    42
moel@1
    43
namespace OpenHardwareMonitor.Hardware.CPU {
moel@1
    44
moel@165
    45
  internal class CPUGroup : IGroup { 
moel@195
    46
    private readonly List<IHardware> hardware = new List<IHardware>();
moel@1
    47
moel@195
    48
    private readonly CPUID[][][] threads;
moel@1
    49
moel@167
    50
    private static CPUID[][] GetProcessorThreads() {
moel@1
    51
moel@90
    52
      List<CPUID> threads = new List<CPUID>();
moel@90
    53
      for (int i = 0; i < 32; i++) {
moel@90
    54
        try {
moel@90
    55
          threads.Add(new CPUID(i));
moel@167
    56
        } catch (ArgumentOutOfRangeException) { }
moel@90
    57
      }
moel@1
    58
moel@90
    59
      SortedDictionary<uint, List<CPUID>> processors =
moel@90
    60
        new SortedDictionary<uint, List<CPUID>>();
moel@90
    61
      foreach (CPUID thread in threads) {
moel@90
    62
        List<CPUID> list;
moel@90
    63
        processors.TryGetValue(thread.ProcessorId, out list);
moel@90
    64
        if (list == null) {
moel@90
    65
          list = new List<CPUID>();
moel@90
    66
          processors.Add(thread.ProcessorId, list);
moel@90
    67
        }
moel@90
    68
        list.Add(thread);
moel@90
    69
      }
moel@90
    70
moel@90
    71
      CPUID[][] processorThreads = new CPUID[processors.Count][];
moel@90
    72
      int index = 0;
moel@90
    73
      foreach (List<CPUID> list in processors.Values) {
moel@90
    74
        processorThreads[index] = list.ToArray();
moel@90
    75
        index++;
moel@90
    76
      }
moel@90
    77
      return processorThreads;
moel@90
    78
    }
moel@90
    79
moel@195
    80
    private static CPUID[][] GroupThreadsByCore(IEnumerable<CPUID> threads) {
moel@90
    81
moel@90
    82
      SortedDictionary<uint, List<CPUID>> cores = 
moel@90
    83
        new SortedDictionary<uint, List<CPUID>>();
moel@90
    84
      foreach (CPUID thread in threads) {
moel@90
    85
        List<CPUID> coreList;
moel@90
    86
        cores.TryGetValue(thread.CoreId, out coreList);
moel@90
    87
        if (coreList == null) {
moel@90
    88
          coreList = new List<CPUID>();
moel@90
    89
          cores.Add(thread.CoreId, coreList);
moel@90
    90
        }
moel@90
    91
        coreList.Add(thread);
moel@90
    92
      }
moel@90
    93
moel@90
    94
      CPUID[][] coreThreads = new CPUID[cores.Count][];
moel@90
    95
      int index = 0;
moel@90
    96
      foreach (List<CPUID> list in cores.Values) {
moel@90
    97
        coreThreads[index] = list.ToArray();
moel@90
    98
        index++;
moel@90
    99
      }
moel@90
   100
      return coreThreads;
moel@1
   101
    }
moel@1
   102
moel@165
   103
    public CPUGroup(ISettings settings) {
moel@1
   104
moel@90
   105
      CPUID[][] processorThreads = GetProcessorThreads();
moel@90
   106
      this.threads = new CPUID[processorThreads.Length][][];
moel@1
   107
moel@90
   108
      int index = 0;
moel@90
   109
      foreach (CPUID[] threads in processorThreads) {
moel@90
   110
        if (threads.Length == 0)
moel@90
   111
          continue;
moel@90
   112
            
moel@90
   113
        CPUID[][] coreThreads = GroupThreadsByCore(threads);
moel@1
   114
moel@191
   115
        this.threads[index] = coreThreads;
moel@1
   116
moel@90
   117
        switch (threads[0].Vendor) {
moel@90
   118
          case Vendor.Intel:
moel@165
   119
            hardware.Add(new IntelCPU(index, coreThreads, settings));
moel@1
   120
            break;
moel@90
   121
          case Vendor.AMD:
moel@90
   122
            switch (threads[0].Family) {
moel@90
   123
              case 0x0F:
moel@165
   124
                hardware.Add(new AMD0FCPU(index, coreThreads, settings));
moel@90
   125
                break;
moel@90
   126
              case 0x10:
moel@165
   127
                hardware.Add(new AMD10CPU(index, coreThreads, settings));
moel@90
   128
                break;
moel@90
   129
              default:
moel@191
   130
                hardware.Add(new GenericCPU(index, coreThreads, settings));
moel@90
   131
                break;
moel@90
   132
            } break;
moel@1
   133
          default:
moel@191
   134
            hardware.Add(new GenericCPU(index, coreThreads, settings));
moel@1
   135
            break;
moel@101
   136
        }
moel@101
   137
moel@101
   138
        index++;
moel@1
   139
      }
moel@1
   140
    }
moel@90
   141
    
moel@1
   142
    public IHardware[] Hardware {
moel@1
   143
      get {
moel@1
   144
        return hardware.ToArray();
moel@1
   145
      }
moel@1
   146
    }
moel@1
   147
moel@167
   148
    private static void AppendCpuidData(StringBuilder r, uint[,] data, 
moel@167
   149
      uint offset) 
moel@167
   150
    {
moel@1
   151
      for (int i = 0; i < data.GetLength(0); i++) {
moel@1
   152
        r.Append(" ");
moel@166
   153
        r.Append((i + offset).ToString("X8", CultureInfo.InvariantCulture));
moel@1
   154
        for (int j = 0; j < 4; j++) {
moel@1
   155
          r.Append("  ");
moel@166
   156
          r.Append(data[i, j].ToString("X8", CultureInfo.InvariantCulture));
moel@1
   157
        }
moel@1
   158
        r.AppendLine();
moel@1
   159
      }
moel@1
   160
    }
moel@1
   161
moel@1
   162
    public string GetReport() {
moel@125
   163
      if (threads == null)
moel@125
   164
        return null;
moel@125
   165
      
moel@1
   166
      StringBuilder r = new StringBuilder();
moel@90
   167
      
moel@1
   168
      r.AppendLine("CPUID");
moel@1
   169
      r.AppendLine();
moel@1
   170
moel@90
   171
      for (int i = 0; i < threads.Length; i++) {
moel@1
   172
moel@90
   173
        r.AppendLine("Processor " + i);
moel@18
   174
        r.AppendLine();
moel@90
   175
        r.AppendFormat("Processor Vendor: {0}{1}", threads[i][0][0].Vendor,
moel@90
   176
          Environment.NewLine);
moel@90
   177
        r.AppendFormat("Processor Brand: {0}{1}", threads[i][0][0].BrandString,
moel@90
   178
          Environment.NewLine);
moel@90
   179
        r.AppendFormat("Family: 0x{0}{1}", 
moel@166
   180
          threads[i][0][0].Family.ToString("X", CultureInfo.InvariantCulture), 
moel@166
   181
          Environment.NewLine);
moel@166
   182
        r.AppendFormat("Model: 0x{0}{1}",
moel@166
   183
          threads[i][0][0].Model.ToString("X", CultureInfo.InvariantCulture), 
moel@166
   184
          Environment.NewLine);
moel@166
   185
        r.AppendFormat("Stepping: 0x{0}{1}",
moel@166
   186
          threads[i][0][0].Stepping.ToString("X", CultureInfo.InvariantCulture), 
moel@166
   187
          Environment.NewLine);
moel@90
   188
        r.AppendLine();
moel@90
   189
moel@90
   190
        r.AppendLine("CPUID Return Values");
moel@90
   191
        r.AppendLine();
moel@90
   192
        for (int j = 0; j < threads[i].Length; j++)
moel@90
   193
          for (int k = 0; k < threads[i][j].Length; k++) {
moel@90
   194
            r.AppendLine(" CPU Thread: " + threads[i][j][k].Thread);
moel@90
   195
            r.AppendLine(" APIC ID: " + threads[i][j][k].ApicId);
moel@90
   196
            r.AppendLine(" Processor ID: " + threads[i][j][k].ProcessorId);
moel@90
   197
            r.AppendLine(" Core ID: " + threads[i][j][k].CoreId);
moel@90
   198
            r.AppendLine(" Thread ID: " + threads[i][j][k].ThreadId);
moel@90
   199
            r.AppendLine();
moel@90
   200
            r.AppendLine(" Function  EAX       EBX       ECX       EDX");
moel@90
   201
            AppendCpuidData(r, threads[i][j][k].Data, CPUID.CPUID_0);
moel@90
   202
            AppendCpuidData(r, threads[i][j][k].ExtData, CPUID.CPUID_EXT);
moel@90
   203
            r.AppendLine();
moel@90
   204
          }
moel@18
   205
      }
moel@90
   206
      return r.ToString(); 
moel@1
   207
    }
moel@1
   208
moel@1
   209
    public void Close() { }
moel@1
   210
  }
moel@1
   211
}