Processor Counter Monitor
PCMService.h
1 // SPDX-License-Identifier: BSD-3-Clause
2 // Copyright (c) 2009-2012, Intel Corporation
3 /*
4 ** Written by Otto Bruggeman, Roman Dementiev
5 */
6 
7 #pragma once
8 
9 #pragma unmanaged
10 #include "pcm-lib.h"
11 #include "windriver.h"
12 #include <stdexcept>
13 
14 #ifndef UNICODE
15 #include <locale>
16 #include <codecvt>
17 #endif
18 #pragma managed
19 
20 using namespace pcm;
21 using namespace System;
22 using namespace System::Collections;
23 using namespace System::ServiceProcess;
24 using namespace System::ComponentModel;
25 using namespace System::Diagnostics;
26 using namespace System::Threading;
27 using namespace System::Runtime::InteropServices;
28 
29 namespace PCMServiceNS {
30  ref struct Globals
31  {
32  static initonly String^ ServiceName = gcnew String(L"PCMService");
33  };
34 
35  ref struct CollectionInformation {
37  {
38  core = true;
39  socket = true;
40  qpi = true;
41  }
42 
44  {
45  core = copyable->core;
46  socket = copyable->socket;
47  qpi = copyable->qpi;
48  }
49 
50  bool core;
51  bool socket;
52  bool qpi;
53  };
54 
55  ref class MeasureThread
56  {
57  public:
58  MeasureThread(System::Diagnostics::EventLog^ log, int sampleRate, CollectionInformation^ collectionInformation) : log_(log), sampleRate_(sampleRate), collectionInformation_(collectionInformation)
59  {
60  // Get a Monitor instance which sets up the PMU, it also figures out the number of cores and sockets which we need later on to create the performance counters
61  m_ = PCM::getInstance();
62  if ( !m_->good() )
63  {
64  log_->WriteEntry(Globals::ServiceName, "Monitor Instance could not be created.", EventLogEntryType::Error);
65  m_->cleanup();
66  String^ s = gcnew String(m_->getErrorMessage().c_str());
67  throw gcnew Exception(s);
68  }
69  log_->WriteEntry(Globals::ServiceName, "PCM: Number of cores detected: " + UInt32(m_->getNumCores()).ToString());
70 
71  m_->program();
72 
73  log_->WriteEntry(Globals::ServiceName, "PMU Programmed.");
74 
75  CountersQpi = gcnew String(L"PCM " + gcnew System::String(m_->xPI()) + L" Counters");
76  MetricQpiBand = gcnew String(gcnew System::String(m_->xPI()) + L" Link Bandwidth");
77 
78  // This here will only create the necessary registry entries, the actual counters are created later.
79  // New unified category
80  if (PerformanceCounterCategory::Exists(CountersCore))
81  {
82  PerformanceCounterCategory::Delete(CountersCore);
83  }
84  if (PerformanceCounterCategory::Exists(CountersSocket))
85  {
86  PerformanceCounterCategory::Delete(CountersSocket);
87  }
88  if (PerformanceCounterCategory::Exists(CountersQpi))
89  {
90  PerformanceCounterCategory::Delete(CountersQpi);
91  }
92  log_->WriteEntry(Globals::ServiceName, "Old categories deleted.");
93 
94  // First create the collection, then add counters to it so we add them all at once
95  CounterCreationDataCollection^ counterCollection = gcnew CounterCreationDataCollection;
96 
97  // Here we add the counters one by one, need list of counters currently collected.
98  // This is a stub: copy and paste when new counters are added to ipcustat "library".
99  // CounterCreationData^ counter = gcnew CounterCreationData( "counter", "helptext for counter", PerformanceCounterType::NumberOfItems64 );
100  // counterCollection->Add( counter );
101  CounterCreationData^ counter;
102 
103  if (collectionInformation_->core)
104  {
105  counter = gcnew CounterCreationData(MetricCoreClocktick, "Displays the number of clockticks elapsed since previous measurement.", PerformanceCounterType::CounterDelta64);
106  counterCollection->Add( counter );
107  counter = gcnew CounterCreationData(MetricCoreRetired, "Displays the number of instructions retired since previous measurement.", PerformanceCounterType::CounterDelta64);
108  counterCollection->Add( counter );
109  counter = gcnew CounterCreationData(MetricCoreMissL2, "Displays the L2 Cache Misses caused by this core.", PerformanceCounterType::CounterDelta64);
110  counterCollection->Add( counter );
111  counter = gcnew CounterCreationData(MetricCoreMissL3, "Displays the L3 Cache Misses caused by this core.", PerformanceCounterType::CounterDelta64);
112  counterCollection->Add( counter );
113  counter = gcnew CounterCreationData(MetricCoreIpc, "Displays the instructions per clocktick executed for this core.", PerformanceCounterType::AverageCount64);
114  counterCollection->Add( counter );
115  counter = gcnew CounterCreationData(MetricCoreBaseIpc, "Not visible", PerformanceCounterType::AverageBase);
116  counterCollection->Add( counter );
117  counter = gcnew CounterCreationData(MetricCoreFreqRel, "Displays the current frequency of the core to its rated frequency in percent.", PerformanceCounterType::SampleFraction);
118  counterCollection->Add( counter );
119  counter = gcnew CounterCreationData(MetricCoreFreqNom, "Not visible", PerformanceCounterType::SampleBase);
120  counterCollection->Add( counter );
121  counter = gcnew CounterCreationData(MetricCoreHeadroom, "Displays temperature reading in 1 degree Celsius relative to the TjMax temperature. 0 corresponds to the max temperature.", PerformanceCounterType::NumberOfItems64);
122  counterCollection->Add( counter );
123  counter = gcnew CounterCreationData(MetricCoreResC0, "Displays the residency of core or socket in core C0-state in percent.", PerformanceCounterType::RawFraction);
124  counterCollection->Add( counter );
125  counter = gcnew CounterCreationData(MetricCoreResC0Base, "", PerformanceCounterType::RawBase);
126  counterCollection->Add( counter );
127  counter = gcnew CounterCreationData(MetricCoreResC1, "Displays the residency of core or socket in core C1-state in percent.", PerformanceCounterType::RawFraction);
128  counterCollection->Add( counter );
129  counter = gcnew CounterCreationData(MetricCoreResC1Base, "", PerformanceCounterType::RawBase);
130  counterCollection->Add(counter);
131  counter = gcnew CounterCreationData(MetricCoreResC3, "Displays the residency of core or socket in core C3-state in percent.", PerformanceCounterType::RawFraction);
132  counterCollection->Add( counter );
133  counter = gcnew CounterCreationData(MetricCoreResC3Base, "", PerformanceCounterType::RawBase);
134  counterCollection->Add(counter);
135  counter = gcnew CounterCreationData(MetricCoreResC6, "Displays the residency of core or socket in core C6-state in percent.", PerformanceCounterType::RawFraction);
136  counterCollection->Add( counter );
137  counter = gcnew CounterCreationData(MetricCoreResC6Base, "", PerformanceCounterType::RawBase);
138  counterCollection->Add(counter);
139  counter = gcnew CounterCreationData(MetricCoreResC7, "Displays the residency of core or socket in core C7-state in percent.", PerformanceCounterType::RawFraction);
140  counterCollection->Add( counter );
141  counter = gcnew CounterCreationData(MetricCoreResC7Base, "", PerformanceCounterType::RawBase);
142  counterCollection->Add(counter);
143  PerformanceCounterCategory::Create(CountersCore, "Processor Counter Monitor", PerformanceCounterCategoryType::MultiInstance, counterCollection);
144  }
145 
146  if (collectionInformation_->socket)
147  {
148  counterCollection->Clear();
149  counter = gcnew CounterCreationData(MetricSocketBandRead, "Displays the memory read bandwidth in bytes/s of this socket.", PerformanceCounterType::NumberOfItems64);
150  counterCollection->Add( counter );
151  counter = gcnew CounterCreationData(MetricSocketBandWrite, "Displays the memory write bandwidth in bytes/s of this socket.", PerformanceCounterType::NumberOfItems64);
152  counterCollection->Add( counter );
153  counter = gcnew CounterCreationData(MetricSocketEnergyPack, "Displays the energy in Joules consumed by this socket.", PerformanceCounterType::NumberOfItems64);
154  counterCollection->Add( counter );
155  counter = gcnew CounterCreationData(MetricSocketEnergyDram, "Displays the energy in Joules consumed by DRAM memory attached to the memory controller of this socket.", PerformanceCounterType::NumberOfItems64);
156  counterCollection->Add( counter );
157  counter = gcnew CounterCreationData(MetricSocketResC0, "Displays the residency of socket in package C0-state in percent.", PerformanceCounterType::RawFraction);
158  counterCollection->Add( counter );
159  counter = gcnew CounterCreationData(MetricSocketResC0Base, "", PerformanceCounterType::RawBase);
160  counterCollection->Add(counter);
161  counter = gcnew CounterCreationData(MetricSocketResC2, "Displays the residency of socket in package C2-state in percent.", PerformanceCounterType::RawFraction);
162  counterCollection->Add( counter );
163  counter = gcnew CounterCreationData(MetricSocketResC2Base, "", PerformanceCounterType::RawBase);
164  counterCollection->Add(counter);
165  counter = gcnew CounterCreationData(MetricSocketResC3, "Displays the residency of socket in package C3-state in percent.", PerformanceCounterType::RawFraction);
166  counterCollection->Add( counter );
167  counter = gcnew CounterCreationData(MetricSocketResC3Base, "", PerformanceCounterType::RawBase);
168  counterCollection->Add(counter);
169  counter = gcnew CounterCreationData(MetricSocketResC6, "Displays the residency of socket in package C6-state in percent.", PerformanceCounterType::RawFraction);
170  counterCollection->Add( counter );
171  counter = gcnew CounterCreationData(MetricSocketResC6Base, "", PerformanceCounterType::RawBase);
172  counterCollection->Add(counter);
173  counter = gcnew CounterCreationData(MetricSocketResC7, "Displays the residency of socket in package C7-state in percent.", PerformanceCounterType::RawFraction);
174  counterCollection->Add( counter );
175  counter = gcnew CounterCreationData(MetricSocketResC7Base, "", PerformanceCounterType::RawBase);
176  counterCollection->Add(counter);
177  counter = gcnew CounterCreationData(MetricSocketResC8, "Displays the residency of socket in package C8-state in percent.", PerformanceCounterType::RawFraction);
178  counterCollection->Add( counter );
179  counter = gcnew CounterCreationData(MetricSocketResC8Base, "", PerformanceCounterType::RawBase);
180  counterCollection->Add(counter);
181  counter = gcnew CounterCreationData(MetricSocketResC9, "Displays the residency of socket in package C9-state in percent.", PerformanceCounterType::RawFraction);
182  counterCollection->Add( counter );
183  counter = gcnew CounterCreationData(MetricSocketResC9Base, "", PerformanceCounterType::RawBase);
184  counterCollection->Add(counter);
185  counter = gcnew CounterCreationData(MetricSocketResC10, "Displays the residency of socket in package C10-state in percent.", PerformanceCounterType::RawFraction);
186  counterCollection->Add( counter );
187  counter = gcnew CounterCreationData(MetricSocketResC10Base, "", PerformanceCounterType::RawBase);
188  counterCollection->Add(counter);
189  PerformanceCounterCategory::Create(CountersSocket, "Processor Counter Monitor", PerformanceCounterCategoryType::MultiInstance, counterCollection);
190  }
191 
192  if (collectionInformation_->qpi)
193  {
194  counterCollection->Clear();
195  counter = gcnew CounterCreationData(MetricQpiBand, L"Displays the incoming bandwidth in bytes/s of this " + gcnew System::String(m_->xPI()) + L" link", PerformanceCounterType::CounterDelta64);
196  counterCollection->Add( counter );
197  PerformanceCounterCategory::Create(CountersQpi, "Processor Counter Monitor", PerformanceCounterCategoryType::MultiInstance, counterCollection);
198  }
199 
200  log_->WriteEntry(Globals::ServiceName, "New categories added.");
201 
202  // Registry entries created, now we need to create the programmatic counters. For some things you may want one instance for every core/thread/socket/qpilink so create in a loop.
203  // PerformanceCounter^ pc1 = gcnew PerformanceCounter( "SomeCounterName", "nameOfCounterAsEnteredInTheRegistry", "instanceNameOfCounterAsANumber" );
204 
205  // Create #processors instances of the core specific performance counters
206  String^ s; // Used for creating the instance name and the string to search for in the hashtable
207  PerformanceCounter^ pc;
208  for ( unsigned int i = 0; i < m_->getNumCores(); ++i )
209  {
210  s = UInt32(i).ToString(); // For core counters we use just the number of the core
211  if (collectionInformation_->core)
212  {
213  ticksHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreClocktick, s, false));
214  instRetHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreRetired, s, false));
215  l2CacheMissHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreMissL2, s, false));
216  l3CacheMissHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreMissL3, s, false));
217  ipcHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreIpc, s, false));
218  baseTicksForIpcHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreBaseIpc, s, false));
219  relFreqHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreFreqRel, s, false));
220  baseTicksForRelFreqHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreFreqNom, s, false));
221  thermalHeadroomHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreHeadroom, s, false));
222  CoreC0StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC0, s, false));
223  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC0Base, s, false);
224  pc->RawValue = 1000;
225  baseArrayList_.Add(pc);
226  CoreC1StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC1, s, false));
227  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC1Base, s, false);
228  pc->RawValue = 1000;
229  baseArrayList_.Add(pc);
230  CoreC3StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC3, s, false));
231  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC3Base, s, false);
232  pc->RawValue = 1000;
233  baseArrayList_.Add(pc);
234  CoreC6StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC6, s, false));
235  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC6Base, s, false);
236  pc->RawValue = 1000;
237  baseArrayList_.Add(pc);
238  CoreC7StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC7, s, false));
239  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC7Base, s, false);
240  pc->RawValue = 1000;
241  baseArrayList_.Add(pc);
242  }
243  }
244 
245  // Create socket instances of the common core counters, names are Socket+number
246  for ( unsigned int i=0; i<m_->getNumSockets(); ++i )
247  {
248  s = "Socket"+UInt32(i).ToString();
249  if (collectionInformation_->core)
250  {
251  ticksHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreClocktick, s, false));
252  instRetHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreRetired, s, false));
253  l2CacheMissHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreMissL2, s, false));
254  l3CacheMissHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreMissL3, s, false));
255  ipcHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreIpc, s, false));
256  baseTicksForIpcHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreBaseIpc, s, false));
257  relFreqHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreFreqRel, s, false));
258  baseTicksForRelFreqHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreFreqNom, s, false));
259  thermalHeadroomHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreHeadroom, s, false));
260  CoreC0StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC0, s, false));
261  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC0Base, s, false);
262  pc->RawValue = 1000;
263  baseArrayList_.Add(pc);
264  CoreC1StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC1, s, false));
265  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC1Base, s, false);
266  pc->RawValue = 1000;
267  baseArrayList_.Add(pc);
268  CoreC3StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC3, s, false));
269  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC3Base, s, false);
270  pc->RawValue = 1000;
271  baseArrayList_.Add(pc);
272  CoreC6StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC6, s, false));
273  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC6Base, s, false);
274  pc->RawValue = 1000;
275  baseArrayList_.Add(pc);
276  CoreC7StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC7, s, false));
277  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC7Base, s, false);
278  pc->RawValue = 1000;
279  baseArrayList_.Add(pc);
280  }
281 
282  if (collectionInformation_->socket)
283  {
284  mrbHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketBandRead, s, false));
285  mwbHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketBandWrite, s, false));
286  packageEnergyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketEnergyPack, s, false));
287  DRAMEnergyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketEnergyDram, s, false));
288  PackageC0StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC0, s, false));
289  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC0Base, s, false);
290  pc->RawValue = 1000;
291  baseArrayList_.Add(pc);
292  PackageC2StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC2, s, false));
293  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC2Base, s, false);
294  pc->RawValue = 1000;
295  baseArrayList_.Add(pc);
296  PackageC3StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC3, s, false));
297  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC3Base, s, false);
298  pc->RawValue = 1000;
299  baseArrayList_.Add(pc);
300  PackageC6StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC6, s, false));
301  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC6Base, s, false);
302  pc->RawValue = 1000;
303  baseArrayList_.Add(pc);
304  PackageC7StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC7, s, false));
305  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC7Base, s, false);
306  pc->RawValue = 1000;
307  baseArrayList_.Add(pc);
308  PackageC8StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC8, s, false));
309  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC8Base, s, false);
310  pc->RawValue = 1000;
311  baseArrayList_.Add(pc);
312  PackageC9StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC9, s, false));
313  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC9Base, s, false);
314  pc->RawValue = 1000;
315  baseArrayList_.Add(pc);
316  PackageC10StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC10, s, false));
317  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC10Base, s, false);
318  pc->RawValue = 1000;
319  baseArrayList_.Add(pc);
320  }
321 
322  if (collectionInformation_->qpi)
323  {
324  qpiHash_.Add(s, gcnew PerformanceCounter(CountersQpi, MetricQpiBand, s, false)); // Socket aggregate
325  String^ t;
326  for ( unsigned int j=0; j<m_->getQPILinksPerSocket(); ++j )
327  {
328  t = s + "_Link" + UInt32(j).ToString();
329  qpiHash_.Add(t, gcnew PerformanceCounter(CountersQpi, MetricQpiBand, t, false));
330  }
331  }
332  }
333 
334  // Create #system instances of the system specific performance counters, just kidding, there is only one system so 1 instance
335  s = "Total_";
336  if (collectionInformation_->core)
337  {
338  ticksHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreClocktick, s, false));
339  instRetHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreRetired, s, false));
340  l2CacheMissHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreMissL2, s, false));
341  l3CacheMissHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreMissL3, s, false));
342  ipcHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreIpc, s, false));
343  baseTicksForIpcHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreBaseIpc, s, false));
344  relFreqHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreFreqRel, s, false));
345  baseTicksForRelFreqHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreFreqNom, s, false));
346  thermalHeadroomHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreHeadroom, s, false));
347  CoreC0StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC0, s, false));
348  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC0Base, s, false);
349  pc->RawValue = 1000;
350  baseArrayList_.Add(pc);
351  CoreC1StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC1, s, false));
352  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC1Base, s, false);
353  pc->RawValue = 1000;
354  baseArrayList_.Add(pc);
355  CoreC3StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC3, s, false));
356  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC3Base, s, false);
357  pc->RawValue = 1000;
358  baseArrayList_.Add(pc);
359  CoreC6StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC6, s, false));
360  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC6Base, s, false);
361  pc->RawValue = 1000;
362  baseArrayList_.Add(pc);
363  CoreC7StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersCore, MetricCoreResC7, s, false));
364  pc = gcnew PerformanceCounter(CountersCore, MetricCoreResC7Base, s, false);
365  pc->RawValue = 1000;
366  baseArrayList_.Add(pc);
367  }
368 
369  if (collectionInformation_->socket)
370  {
371  mrbHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketBandRead, s, false));
372  mwbHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketBandWrite, s, false));
373  packageEnergyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketEnergyPack, s, false));
374  DRAMEnergyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketEnergyDram, s, false));
375  PackageC0StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC0, s, false));
376  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC0Base, s, false);
377  pc->RawValue = 1000;
378  baseArrayList_.Add(pc);
379  PackageC2StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC2, s, false));
380  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC2Base, s, false);
381  pc->RawValue = 1000;
382  baseArrayList_.Add(pc);
383  PackageC3StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC3, s, false));
384  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC3Base, s, false);
385  pc->RawValue = 1000;
386  baseArrayList_.Add(pc);
387  PackageC6StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC6, s, false));
388  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC6Base, s, false);
389  pc->RawValue = 1000;
390  baseArrayList_.Add(pc);
391  PackageC7StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC7, s, false));
392  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC7Base, s, false);
393  pc->RawValue = 1000;
394  baseArrayList_.Add(pc);
395  PackageC8StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC8, s, false));
396  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC8Base, s, false);
397  pc->RawValue = 1000;
398  baseArrayList_.Add(pc);
399  PackageC9StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC9, s, false));
400  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC9Base, s, false);
401  pc->RawValue = 1000;
402  baseArrayList_.Add(pc);
403  PackageC10StateResidencyHash_.Add(s, gcnew PerformanceCounter(CountersSocket, MetricSocketResC10, s, false));
404  pc = gcnew PerformanceCounter(CountersSocket, MetricSocketResC10Base, s, false);
405  pc->RawValue = 1000;
406  baseArrayList_.Add(pc);
407  }
408 
409  if (collectionInformation_->qpi)
410  {
411  qpiHash_.Add(s, gcnew PerformanceCounter(CountersQpi, MetricQpiBand, s, false));
412  }
413 
414  log_->WriteEntry(Globals::ServiceName, "All instances of the performance counter categories have been created.");
415  }
416 
417  void doMeasurements( void )
418  {
419  // FIXME: Do we care about hot swappability of CPUs?
420  const size_t numSockets = m_->getNumSockets();
421  const size_t numCores = m_->getNumCores();
422  const size_t numQpiLinks = (size_t) m_->getQPILinksPerSocket();
423 
424  SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
425 
426  // The structures
427  SystemCounterState oldSystemState;
428  std::vector<SocketCounterState> oldSocketStates;
429  std::vector<CoreCounterState> oldCoreStates;
430  SystemCounterState systemState;
431  std::vector<SocketCounterState> socketStates;
432  std::vector<CoreCounterState> coreStates;
433  ULONGLONG BeforeTime = 0, AfterTime = 0;
434 
435  m_->getAllCounterStates(oldSystemState, oldSocketStates, oldCoreStates);
436  BeforeTime = GetTickCount64();
437 
438  // labmda functions are not allowed in managed code, using a macro
439 #define toBW(val) (val * 1000ULL / (AfterTime - BeforeTime))
440 
441  try {
442  while (true)
443  {
444  Thread::Sleep(sampleRate_);
445 
446  // Fetch counter data here and store in the PerformanceCounter instances
447  m_->getAllCounterStates(systemState, socketStates, coreStates);
448  AfterTime = GetTickCount64();
449 
450  // Set system performance counters
451  String^ s = "Total_";
452  if (collectionInformation_->core)
453  {
454  __int64 totalTicks = getCycles(systemState);
455  __int64 totalRefTicks = m_->getNominalFrequency() * numCores;
456  __int64 totalInstr = getInstructionsRetired(systemState);
457  ((PerformanceCounter^)ticksHash_[s])->RawValue = totalTicks;
458  ((PerformanceCounter^)instRetHash_[s])->RawValue = totalInstr;
459  ((PerformanceCounter^)l2CacheMissHash_[s])->IncrementBy(getL2CacheMisses(oldSystemState, systemState));
460  ((PerformanceCounter^)l3CacheMissHash_[s])->IncrementBy(getL3CacheMisses(oldSystemState, systemState));
461  ((PerformanceCounter^)ipcHash_[s])->RawValue = totalInstr >> 17;
462  ((PerformanceCounter^)baseTicksForIpcHash_[s])->RawValue = totalTicks >> 17;
463  ((PerformanceCounter^)relFreqHash_[s])->RawValue = totalTicks >> 17;
464  ((PerformanceCounter^)baseTicksForRelFreqHash_[s])->IncrementBy(totalRefTicks >> 17);
465  ((PerformanceCounter^)thermalHeadroomHash_[s])->RawValue = systemState.getThermalHeadroom();
466  ((PerformanceCounter^)CoreC0StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(0,oldSystemState, systemState));
467  ((PerformanceCounter^)CoreC1StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(1,oldSystemState, systemState));
468  ((PerformanceCounter^)CoreC3StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(3,oldSystemState, systemState));
469  ((PerformanceCounter^)CoreC6StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(6,oldSystemState, systemState));
470  ((PerformanceCounter^)CoreC7StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(7,oldSystemState, systemState));
471  //log_->WriteEntry(Globals::ServiceName, "Std: " + UInt64(totalTicks).ToString());
472  //log_->WriteEntry(Globals::ServiceName, "Ref: " + UInt64(totalRefTicks).ToString());
473  }
474 
475  if (collectionInformation_->socket)
476  {
477  ((PerformanceCounter^)mrbHash_[s])->RawValue = toBW(getBytesReadFromMC(oldSystemState, systemState));
478  ((PerformanceCounter^)mwbHash_[s])->RawValue = toBW(getBytesWrittenToMC(oldSystemState, systemState));
479  ((PerformanceCounter^)packageEnergyHash_[s])->RawValue = (__int64)getConsumedJoules(oldSystemState, systemState);
480  ((PerformanceCounter^)DRAMEnergyHash_[s])->RawValue = (__int64)getDRAMConsumedJoules(oldSystemState, systemState);
481  ((PerformanceCounter^)PackageC0StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency( 0, oldSystemState, systemState));
482  ((PerformanceCounter^)PackageC2StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency( 2, oldSystemState, systemState));
483  ((PerformanceCounter^)PackageC3StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency( 3, oldSystemState, systemState));
484  ((PerformanceCounter^)PackageC6StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency( 6, oldSystemState, systemState));
485  ((PerformanceCounter^)PackageC7StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency( 7, oldSystemState, systemState));
486  ((PerformanceCounter^)PackageC8StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency( 8, oldSystemState, systemState));
487  ((PerformanceCounter^)PackageC9StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency( 9, oldSystemState, systemState));
488  ((PerformanceCounter^)PackageC10StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency(10, oldSystemState, systemState));
489  }
490 
491  if (collectionInformation_->qpi)
492  {
493  ((PerformanceCounter^)qpiHash_[s])->RawValue = getAllIncomingQPILinkBytes(systemState);
494  }
495 
496  // Set socket performance counters
497  for ( unsigned int i = 0; i < numSockets; ++i )
498  {
499  s = "Socket"+UInt32(i).ToString();
500  const SocketCounterState & socketState = socketStates[i];
501  if (collectionInformation_->core)
502  {
503  __int64 socketTicks = getCycles(socketState);
504  __int64 socketRefTicks = m_->getNominalFrequency()* numCores / numSockets;
505  __int64 socketInstr = getInstructionsRetired(socketState);
506  ((PerformanceCounter^)instRetHash_[s])->RawValue = socketInstr;
507  ((PerformanceCounter^)ipcHash_[s])->RawValue = socketInstr >> 17;
508  ((PerformanceCounter^)l2CacheMissHash_[s])->IncrementBy(getL2CacheMisses(oldSocketStates[i], socketState));
509  ((PerformanceCounter^)l3CacheMissHash_[s])->IncrementBy(getL3CacheMisses(oldSocketStates[i], socketState));
510  ((PerformanceCounter^)ticksHash_[s])->RawValue = socketTicks;
511  ((PerformanceCounter^)baseTicksForIpcHash_[s])->RawValue = socketTicks >> 17;
512  ((PerformanceCounter^)relFreqHash_[s])->RawValue = socketTicks >> 17;
513  ((PerformanceCounter^)baseTicksForRelFreqHash_[s])->IncrementBy(socketRefTicks >> 17);
514  ((PerformanceCounter^)thermalHeadroomHash_[s])->RawValue = socketState.getThermalHeadroom();
515  ((PerformanceCounter^)CoreC0StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(0, oldSocketStates[i], socketState));
516  ((PerformanceCounter^)CoreC1StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(1, oldSocketStates[i], socketState));
517  ((PerformanceCounter^)CoreC3StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(3, oldSocketStates[i], socketState));
518  ((PerformanceCounter^)CoreC6StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(6, oldSocketStates[i], socketState));
519  ((PerformanceCounter^)CoreC7StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(7, oldSocketStates[i], socketState));
520  }
521 
522  if (collectionInformation_->socket)
523  {
524  ((PerformanceCounter^)mrbHash_[s])->RawValue = toBW(getBytesReadFromMC(oldSocketStates[i], socketState));
525  ((PerformanceCounter^)mwbHash_[s])->RawValue = toBW(getBytesWrittenToMC(oldSocketStates[i], socketState));
526  ((PerformanceCounter^)packageEnergyHash_[s])->RawValue = (__int64)getConsumedJoules(oldSocketStates[i], socketState);
527  ((PerformanceCounter^)DRAMEnergyHash_[s])->RawValue = (__int64)getDRAMConsumedJoules(oldSocketStates[i], socketState);
528  ((PerformanceCounter^)PackageC0StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency( 0,oldSocketStates[i], socketState));
529  ((PerformanceCounter^)PackageC2StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency( 2,oldSocketStates[i], socketState));
530  ((PerformanceCounter^)PackageC3StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency( 3,oldSocketStates[i], socketState));
531  ((PerformanceCounter^)PackageC6StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency( 6,oldSocketStates[i], socketState));
532  ((PerformanceCounter^)PackageC7StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency( 7,oldSocketStates[i], socketState));
533  ((PerformanceCounter^)PackageC8StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency( 8,oldSocketStates[i], socketState));
534  ((PerformanceCounter^)PackageC9StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency( 9,oldSocketStates[i], socketState));
535  ((PerformanceCounter^)PackageC10StateResidencyHash_[s])->RawValue = __int64(1000. * getPackageCStateResidency(10,oldSocketStates[i], socketState));
536  }
537 
538  if (collectionInformation_->qpi)
539  {
540  ((PerformanceCounter^)qpiHash_[s])->RawValue = toBW(getSocketIncomingQPILinkBytes(i, systemState));
541  String^ t;
542  // and qpi link counters per socket
543  for ( unsigned int j=0; j<numQpiLinks; ++j )
544  {
545  t = s + "_Link" + UInt32(j).ToString();
546  ((PerformanceCounter^)qpiHash_[t])->RawValue = toBW(getIncomingQPILinkBytes(i, j, systemState));
547  }
548  }
549  }
550 
551  // Set core performance counters
552  for ( unsigned int i = 0; i < numCores; ++i )
553  {
554  s = UInt32(i).ToString();
555  const CoreCounterState & coreState = coreStates[i];
556  if (collectionInformation_->core)
557  {
558  __int64 ticks = getCycles(coreState);
559  __int64 refTicks = m_->getNominalFrequency();
560  __int64 instr = getInstructionsRetired(coreState);
561  ((PerformanceCounter^)instRetHash_[s])->RawValue = instr;
562  ((PerformanceCounter^)ipcHash_[s])->RawValue = instr >> 17;
563  ((PerformanceCounter^)l2CacheMissHash_[s])->IncrementBy(getL2CacheMisses(oldCoreStates[i], coreState));
564  ((PerformanceCounter^)l3CacheMissHash_[s])->IncrementBy(getL3CacheMisses(oldCoreStates[i], coreState));
565  ((PerformanceCounter^)ticksHash_[s])->RawValue = ticks;
566  ((PerformanceCounter^)baseTicksForIpcHash_[s])->RawValue = ticks >> 17;
567  ((PerformanceCounter^)relFreqHash_[s])->RawValue = ticks >> 17;
568  ((PerformanceCounter^)baseTicksForRelFreqHash_[s])->IncrementBy(refTicks >> 17);
569  ((PerformanceCounter^)thermalHeadroomHash_[s])->RawValue = coreState.getThermalHeadroom();
570  ((PerformanceCounter^)CoreC0StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(0,oldCoreStates[i], coreState));
571  ((PerformanceCounter^)CoreC1StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(1,oldCoreStates[i], coreState));
572  ((PerformanceCounter^)CoreC3StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(3,oldCoreStates[i], coreState));
573  ((PerformanceCounter^)CoreC6StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(6,oldCoreStates[i], coreState));
574  ((PerformanceCounter^)CoreC7StateResidencyHash_[s])->RawValue = __int64(1000. * getCoreCStateResidency(7,oldCoreStates[i], coreState));
575  }
576  }
577 
578  std::swap(oldSystemState, systemState);
579  std::swap(oldSocketStates, socketStates);
580  std::swap(oldCoreStates, coreStates);
581  std::swap(BeforeTime, AfterTime);
582  }
583  }
584  catch( ThreadAbortException^ )
585  {
586  // We get here when for instance the service gets stopped or something bad happens.
587  // In order to do our cleanup, like unprogram the MSRs, close the driver and such, in case we get stopped we want to execute normally after this
588  // so this resets the abort and allows a normal exit
589  Thread::ResetAbort();
590  }
591  // Here we now have the chance to do cleanup after catching the ThreadAbortException because of the ResetAbort
592  m_->cleanup();
593  }
594 
595  private:
596  // Core counter hashtables
597  System::Collections::Hashtable ticksHash_;
598  System::Collections::Hashtable instRetHash_;
599  System::Collections::Hashtable ipcHash_;
600  System::Collections::Hashtable baseTicksForIpcHash_;
601  System::Collections::Hashtable relFreqHash_;
602  System::Collections::Hashtable baseTicksForRelFreqHash_;
603  System::Collections::Hashtable l3CacheMissHash_;
604  System::Collections::Hashtable l2CacheMissHash_;
605  // Socket counter hashtables
606  System::Collections::Hashtable mrbHash_;
607  System::Collections::Hashtable mwbHash_;
608  // QPI counter hashtables
609  System::Collections::Hashtable qpiHash_;
610  // Energy counters
611  System::Collections::Hashtable packageEnergyHash_;
612  System::Collections::Hashtable DRAMEnergyHash_;
613  // Thermal headroom
614  System::Collections::Hashtable thermalHeadroomHash_;
615  // C-state Residencies
616  System::Collections::Hashtable CoreC0StateResidencyHash_;
617  System::Collections::Hashtable CoreC1StateResidencyHash_;
618  System::Collections::Hashtable CoreC3StateResidencyHash_;
619  System::Collections::Hashtable CoreC6StateResidencyHash_;
620  System::Collections::Hashtable CoreC7StateResidencyHash_;
621  System::Collections::Hashtable PackageC0StateResidencyHash_;
622  System::Collections::Hashtable PackageC2StateResidencyHash_;
623  System::Collections::Hashtable PackageC3StateResidencyHash_;
624  System::Collections::Hashtable PackageC6StateResidencyHash_;
625  System::Collections::Hashtable PackageC7StateResidencyHash_;
626  System::Collections::Hashtable PackageC8StateResidencyHash_;
627  System::Collections::Hashtable PackageC9StateResidencyHash_;
628  System::Collections::Hashtable PackageC10StateResidencyHash_;
629  System::Collections::ArrayList baseArrayList_;
630 
631  System::Diagnostics::EventLog^ log_;
632 
633  PCM* m_;
634 
635  // Counter variable names
636  initonly String^ CountersCore = gcnew String(L"PCM Core Counters");
637  initonly String^ CountersSocket = gcnew String(L"PCM Socket Counters");
638  initonly String^ CountersQpi;
639 
640  initonly String^ MetricCoreClocktick = gcnew String(L"Clockticks");
641  initonly String^ MetricCoreRetired = gcnew String(L"Instructions Retired");
642  initonly String^ MetricCoreMissL2 = gcnew String(L"L2 Cache Misses");
643  initonly String^ MetricCoreMissL3 = gcnew String(L"L3 Cache Misses");
644  initonly String^ MetricCoreIpc = gcnew String(L"Instructions Per Clocktick (IPC)");
645  initonly String^ MetricCoreBaseIpc = gcnew String(L"Base ticks IPC");
646  initonly String^ MetricCoreFreqRel = gcnew String(L"Relative Frequency (%)");
647  initonly String^ MetricCoreFreqNom = gcnew String(L"Nominal Frequency");
648  initonly String^ MetricCoreHeadroom = gcnew String(L"Thermal Headroom below TjMax");
649  initonly String^ MetricCoreResC0 = gcnew String(L"core C0-state residency (%)");
650  initonly String^ MetricCoreResC1 = gcnew String(L"core C1-state residency (%)");
651  initonly String^ MetricCoreResC3 = gcnew String(L"core C3-state residency (%)");
652  initonly String^ MetricCoreResC6 = gcnew String(L"core C6-state residency (%)");
653  initonly String^ MetricCoreResC7 = gcnew String(L"core C7-state residency (%)");
654  initonly String^ MetricCoreResC0Base = gcnew String(L"core C0-state base");
655  initonly String^ MetricCoreResC1Base = gcnew String(L"core C1-state base");
656  initonly String^ MetricCoreResC3Base = gcnew String(L"core C3-state base");
657  initonly String^ MetricCoreResC6Base = gcnew String(L"core C6-state base");
658  initonly String^ MetricCoreResC7Base = gcnew String(L"core C7-state base");
659 
660  initonly String^ MetricSocketBandRead = gcnew String(L"Memory Read Bandwidth");
661  initonly String^ MetricSocketBandWrite = gcnew String(L"Memory Write Bandwidth");
662  initonly String^ MetricSocketEnergyPack = gcnew String(L"Package/Socket Consumed Energy");
663  initonly String^ MetricSocketEnergyDram = gcnew String(L"DRAM/Memory Consumed Energy");
664  initonly String^ MetricSocketResC0 = gcnew String(L"package C0-state residency (%)");
665  initonly String^ MetricSocketResC2 = gcnew String(L"package C2-state residency (%)");
666  initonly String^ MetricSocketResC3 = gcnew String(L"package C3-state residency (%)");
667  initonly String^ MetricSocketResC6 = gcnew String(L"package C6-state residency (%)");
668  initonly String^ MetricSocketResC7 = gcnew String(L"package C7-state residency (%)");
669  initonly String^ MetricSocketResC8 = gcnew String(L"package C8-state residency (%)");
670  initonly String^ MetricSocketResC9 = gcnew String(L"package C9-state residency (%)");
671  initonly String^ MetricSocketResC10 = gcnew String(L"package C10-state residency (%)");
672  initonly String^ MetricSocketResC0Base = gcnew String(L"package C0-state base");
673  initonly String^ MetricSocketResC2Base = gcnew String(L"package C2-state base");
674  initonly String^ MetricSocketResC3Base = gcnew String(L"package C3-state base");
675  initonly String^ MetricSocketResC6Base = gcnew String(L"package C6-state base");
676  initonly String^ MetricSocketResC7Base = gcnew String(L"package C7-state base");
677  initonly String^ MetricSocketResC8Base = gcnew String(L"package C8-state base");
678  initonly String^ MetricSocketResC9Base = gcnew String(L"package C9-state base");
679  initonly String^ MetricSocketResC10Base = gcnew String(L"package C10-state base");
680 
681  initonly String^ MetricQpiBand;
682 
683  // Configuration values
684  const int sampleRate_;
685  const CollectionInformation^ collectionInformation_;
686  };
687 
697  public ref class PCMService : public System::ServiceProcess::ServiceBase
698  {
699  [DllImport ("advapi32.dll")]
700  static bool SetServiceStatus (IntPtr hServiceStatus, LPSERVICE_STATUS lpServiceStatus);
701 
702  private:
703  void SetServiceFail (int ErrorCode)
704  {
705  SERVICE_STATUS ServiceStatus_;
706  ServiceStatus_.dwCurrentState = (int)SERVICE_STOPPED;
707  ServiceStatus_.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
708  ServiceStatus_.dwWaitHint = 0;
709  ServiceStatus_.dwWin32ExitCode = ErrorCode;
710  ServiceStatus_.dwServiceSpecificExitCode = 0;
711  ServiceStatus_.dwCheckPoint = 0;
712  ServiceStatus_.dwControlsAccepted = 0 |
713  (this->CanStop ? (int) SERVICE_ACCEPT_STOP : 0) |
714  (this->CanShutdown ? (int) SERVICE_ACCEPT_SHUTDOWN : 0) |
715  (this->CanPauseAndContinue ? (int) SERVICE_ACCEPT_PAUSE_CONTINUE : 0) |
716  (this->CanHandleSessionChangeEvent ? (int) SERVICE_ACCEPT_SESSIONCHANGE : 0) |
717  (this->CanHandlePowerEvent ? (int) SERVICE_ACCEPT_POWEREVENT : 0);
718  SetServiceStatus (this->ServiceHandle, &ServiceStatus_);
719  }
720 
721 
722  public:
723  PCMService()
724  {
725  InitializeComponent();
726  //
727  //TODO: Add the constructor code here
728  //
729  }
730  protected:
735  {
736  if (components)
737  {
738  delete components;
739  }
740  }
741 
745  virtual void OnStart(array<String^>^ args) override
746  {
747  PCM* m_ = PCM::getInstance();
748  SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
749  // Default values for configuration
750  int sampleRate = 1000;
751  CollectionInformation^ collectionInformation = gcnew CollectionInformation();
752 
753  // Read configuration values from registry
754  HKEY hkey;
755  if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\pcm\\service"), NULL, KEY_READ, &hkey))
756  {
757  DWORD regDWORD = static_cast<DWORD>(REG_DWORD);
758  DWORD lenDWORD = 32;
759 
760  DWORD sampleRateRead(0);
761  if (ERROR_SUCCESS == RegQueryValueEx(hkey, TEXT("SampleRate"), NULL, NULL, reinterpret_cast<LPBYTE>(&sampleRateRead), &lenDWORD))
762  {
763  sampleRate = (int)sampleRateRead;
764  }
765 
766  DWORD collectCoreRead(0);
767  if (ERROR_SUCCESS == RegQueryValueEx(hkey, TEXT("CollectCore"), NULL, NULL, reinterpret_cast<LPBYTE>(&collectCoreRead), &lenDWORD)) {
768  collectionInformation->core = (int)collectCoreRead > 0;
769  }
770 
771  DWORD collectSocketRead(0);
772  if (ERROR_SUCCESS == RegQueryValueEx(hkey, TEXT("CollectSocket"), NULL, NULL, reinterpret_cast<LPBYTE>(&collectSocketRead), &lenDWORD)) {
773  collectionInformation->socket = (int)collectSocketRead > 0;
774  }
775 
776  DWORD collectQpiRead(0);
777  if (ERROR_SUCCESS == RegQueryValueEx(hkey, TEXT("CollectQpi"), NULL, NULL, reinterpret_cast<LPBYTE>(&collectQpiRead), &lenDWORD)) {
778  collectionInformation->qpi = (int)collectQpiRead > 0;
779  }
780 
781  RegCloseKey(hkey);
782  }
783 
784  this->RequestAdditionalTime(4000);
785  // We should open the driver here
786  EventLog->WriteEntry(Globals::ServiceName, "Trying to start the driver...", EventLogEntryType::Information);
787  drv_ = new Driver;
788  if (!drv_->start())
789  {
790 #ifdef UNICODE
791  const auto& driverPath = drv_->driverPath();
792 #else
793  std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> char_to_wide;
794  std::wstring driverPath = char_to_wide.from_bytes(drv_->driverPath().c_str());
795 #endif
796  String^ s = gcnew String((L"Cannot open the driver.\nYou must have a signed driver at " + driverPath + L" and have administrator rights to run this program.\n\n").c_str());
797  EventLog->WriteEntry(Globals::ServiceName, s, EventLogEntryType::Error);
798  SetServiceFail(ERROR_FILE_NOT_FOUND);
799  throw gcnew Exception(s);
800  }
801 
802  // TODO: Add code here to start your service.
803  MeasureThread^ mt;
804  EventLog->WriteEntry(Globals::ServiceName, "Trying to create the measure thread...", EventLogEntryType::Information);
805  try
806  {
807  mt = gcnew MeasureThread(EventLog, sampleRate, collectionInformation);
808  }
809  catch (Exception^ e)
810  {
811  EventLog->WriteEntry(Globals::ServiceName, "Could not create MeasureThread, aborting", EventLogEntryType::Error);
812  EventLog->WriteEntry(Globals::ServiceName, e->Message, EventLogEntryType::Error);
813  SetServiceFail(0x80886);
814  throw e;
815  }
816 
817  // Create thread, pretty obvious comment here
818  workerThread_ = gcnew Thread( gcnew ThreadStart( mt, &MeasureThread::doMeasurements ) );
819  // Start timer/thread to read out registers and fill performance counter structures
820  workerThread_->Start();
821 // EventLog->WriteEntry("PCMService", System::DateTime::Now.ToLongTimeString() + " Monitor could not initialize PMU, aborting.", EventLogEntryType::Error);
822 
823  }
824 
828  virtual void OnStop() override
829  {
830  // TODO: Add code here to perform any tear-down necessary to stop your service.
831  this->RequestAdditionalTime(4000);
832  // Stop timer/thread
833  // doMeasurements will do cleanup itself, might have to do some sanity checks here
834  workerThread_->Abort();
835  drv_->stop();
836  }
837 
838  private:
842  System::ComponentModel::Container ^components;
843  System::Threading::Thread^ workerThread_;
844  Driver* drv_;
845 
846 #pragma region Windows Form Designer generated code
847  void InitializeComponent(void)
852  {
853  //
854  // PCMService
855  //
856  this->CanPauseAndContinue = true;
857  this->ServiceName = Globals::ServiceName;
858 
859  }
860 #pragma endregion
861  };
862 }
Definition: PCMService.h:30
double getConsumedJoules(const CounterStateType &before, const CounterStateType &after)
Returns Joules consumed by processor (excluding DRAM)
Definition: cpucounters.h:2633
Definition: PCMService.h:29
(Logical) core-wide counter state
Definition: cpucounters.h:2925
Manage custom Windows MSR (Model Specific Register) Driver The driver is required to access hardware ...
Definition: windriver.h:29
double getDRAMConsumedJoules(const CounterStateType &before, const CounterStateType &after)
Returns Joules consumed by DRAM.
Definition: cpucounters.h:2646
uint64 getCycles(const CounterStateType &before, const CounterStateType &after)
Computes the number core clock cycles when signal on a specific core is running (not halted) ...
Definition: cpucounters.h:3136
Definition: PCMService.h:55
double getCoreCStateResidency(int state, const CounterStateType &before, const CounterStateType &after)
Computes residency in the core C-state.
Definition: cpucounters.h:3496
Socket-wide counter state.
Definition: cpucounters.h:2938
Summary for PMCService
Definition: PCMService.h:697
int32 getThermalHeadroom() const
Returns current thermal headroom below TjMax.
Definition: cpucounters.h:2345
Definition: lspci.h:258
virtual void OnStart(array< String^>^ args) override
Set things in motion so your service can do its work.
Definition: PCMService.h:745
uint64 getL2CacheMisses(const CounterStateType &before, const CounterStateType &after)
Computes number of L2 cache misses.
Definition: cpucounters.h:3346
uint64 getInstructionsRetired(const CounterStateType &before, const CounterStateType &after)
Computes the number of retired instructions.
Definition: cpucounters.h:3087
CPU Performance Monitor.
Definition: cpucounters.h:543
static PCM * getInstance()
Returns PCM object.
Definition: cpucounters.cpp:239
Definition: bw.cpp:12
uint64 getIncomingQPILinkBytes(uint32 socketNr, uint32 linkNr, const SystemCounterState &before, const SystemCounterState &after)
Get estimation of QPI data traffic per incoming QPI link.
Definition: cpucounters.h:3734
uint64 getBytesReadFromMC(const CounterStateType &before, const CounterStateType &after)
Computes number of bytes read from DRAM memory controllers.
Definition: cpucounters.h:3578
uint64 getL3CacheMisses(const CounterStateType &before, const CounterStateType &after)
Computes number of L3 cache misses.
Definition: cpucounters.h:3332
uint64 getAllIncomingQPILinkBytes(const SystemCounterState &before, const SystemCounterState &after)
Get estimation of total QPI data traffic.
Definition: cpucounters.h:3840
System-wide counter state.
Definition: cpucounters.h:2978
Definition: PCMService.h:35
~PCMService()
Clean up any resources being used.
Definition: PCMService.h:734
uint64 getBytesWrittenToMC(const CounterStateType &before, const CounterStateType &after)
Computes number of bytes written to DRAM memory controllers.
Definition: cpucounters.h:3592
double getPackageCStateResidency(int state, const CounterStateType &before, const CounterStateType &after)
Computes residency in the package C-state.
Definition: cpucounters.h:3540
uint64 getSocketIncomingQPILinkBytes(uint32 socketNr, const SystemCounterState &now)
Get estimation of total QPI data traffic for this socket.
Definition: cpucounters.h:3901
Loading and unloading custom Windows MSR (Model Specific Register) Driver.
virtual void OnStop() override
Stop this service.
Definition: PCMService.h:828