Processor Counter Monitor
cpuasynchcounter.h
Go to the documentation of this file.
1 // SPDX-License-Identifier: BSD-3-Clause
2 // Copyright (c) 2009-2012, Intel Corporation
3 //
4 // asynchronous CPU conters
5 //
6 // contact: Thomas Willhalm
7 
8 #ifndef CPUASYNCHCOUNTER_HEADER
9 #define CPUASYNCHCOUNTER_HEADER
10 
11 
16 #include <pthread.h>
17 #include <stdlib.h>
18 #include "cpucounters.h"
19 
20 #define DELAY 1 // in seconds
21 
22 using namespace pcm;
23 
24 void * UpdateCounters(void *);
25 
27  PCM * m;
28 
29  CoreCounterState * cstates1, * cstates2;
30  SocketCounterState * skstates1, * skstates2;
31  SystemCounterState sstate1, sstate2;
32 
33  pthread_t UpdateThread;
34  pthread_mutex_t CounterMutex;
35 
36  friend void * UpdateCounters(void *);
37 
39  const AsynchronCounterState & operator = (const AsynchronCounterState &) = delete;
40 
41 public:
43  {
44  m = PCM::getInstance();
45  PCM::ErrorCode status = m->program();
46  if (status != PCM::Success)
47  {
48  std::cerr << "\nCannot access CPU counters. Try to run 'pcm 1' to check the PMU access status.\n\n";
49  exit(-1);
50  }
51 
52  cstates1 = new CoreCounterState[m->getNumCores()];
53  cstates2 = new CoreCounterState[m->getNumCores()];
54  skstates1 = new SocketCounterState[m->getNumSockets()];
55  skstates2 = new SocketCounterState[m->getNumSockets()];
56 
57  for (uint32 i = 0; i < m->getNumCores(); ++i) {
58  cstates1[i] = getCoreCounterState(i);
59  cstates2[i] = getCoreCounterState(i);
60  }
61 
62  for (uint32 i = 0; i < m->getNumSockets(); ++i) {
63  skstates1[i] = getSocketCounterState(i);
64  skstates2[i] = getSocketCounterState(i);
65  }
66 
67  pthread_mutex_init(&CounterMutex, NULL);
68  pthread_create(&UpdateThread, NULL, UpdateCounters, this);
69  }
71  {
72  pthread_cancel(UpdateThread);
73  if (pthread_mutex_destroy(&CounterMutex) != 0) std::cerr << "pthread_mutex_destroy failed\n";
74  m->cleanup();
75  delete[] cstates1;
76  delete[] cstates2;
77  delete[] skstates1;
78  delete[] skstates2;
79  }
80 
81  uint32 getNumCores()
82  { return m->getNumCores(); }
83 
84  uint32 getNumSockets()
85  { return m->getNumSockets(); }
86 
87  uint32 getQPILinksPerSocket()
88  {
89  return m->getQPILinksPerSocket();
90  }
91 
92  uint32 getSocketId(uint32 c)
93  {
94  return m->getSocketId(c);
95  }
96 
97  const char * getXpi() {
98  return m->xPI();
99  }
100 
101  template <typename T, T func(CoreCounterState const &)>
102  T get(uint32 core)
103  {
104  pthread_mutex_lock(&CounterMutex);
105  T value = func(cstates2[core]);
106  pthread_mutex_unlock(&CounterMutex);
107  return value;
108  }
109  template <typename T, T func(CoreCounterState const &, CoreCounterState const &)>
110  T get(uint32 core)
111  {
112  pthread_mutex_lock(&CounterMutex);
113  T value = func(cstates1[core], cstates2[core]);
114  pthread_mutex_unlock(&CounterMutex);
115  return value;
116  }
117 
118  template <typename T, T func(int, CoreCounterState const &, CoreCounterState const &)>
119  T get(int param, uint32 core)
120  {
121  pthread_mutex_lock(&CounterMutex);
122  T value = func(param, cstates1[core], cstates2[core]);
123  pthread_mutex_unlock(&CounterMutex);
124  return value;
125  }
126 
127  template <typename T, T func(SocketCounterState const &)>
128  T getSocket(uint32 socket)
129  {
130  pthread_mutex_lock(&CounterMutex);
131  T value = func(skstates2[socket]);
132  pthread_mutex_unlock(&CounterMutex);
133  return value;
134  }
135 
136  template <typename T, T func(SocketCounterState const &, SocketCounterState const &)>
137  T getSocket(uint32 socket)
138  {
139  pthread_mutex_lock(&CounterMutex);
140  T value = func(skstates1[socket], skstates2[socket]);
141  pthread_mutex_unlock(&CounterMutex);
142  return value;
143  }
144 
145  template <typename T, T func(int, SocketCounterState const &, SocketCounterState const &)>
146  T getSocket(int param, uint32 socket)
147  {
148  pthread_mutex_lock(&CounterMutex);
149  T value = func(param, skstates1[socket], skstates2[socket]);
150  pthread_mutex_unlock(&CounterMutex);
151  return value;
152  }
153 
154  template <typename T, T func(uint32, uint32, SystemCounterState const &, SystemCounterState const &)>
155  T getSocket(uint32 socket, uint32 param)
156  {
157  pthread_mutex_lock(&CounterMutex);
158  T value = func(socket, param, sstate1, sstate2);
159  pthread_mutex_unlock(&CounterMutex);
160  return value;
161  }
162 
163  template <typename T, T func(SystemCounterState const &, SystemCounterState const &)>
164  T getSystem()
165  {
166  pthread_mutex_lock(&CounterMutex);
167  T value = func(sstate1, sstate2);
168  pthread_mutex_unlock(&CounterMutex);
169  return value;
170  }
171 
172  template <typename T, T func(int, SystemCounterState const &, SystemCounterState const &)>
173  T getSystem(int param)
174  {
175  pthread_mutex_lock(&CounterMutex);
176  T value = func(param, sstate1, sstate2);
177  pthread_mutex_unlock(&CounterMutex);
178  return value;
179  }
180 };
181 
182 void * UpdateCounters(void * state)
183 {
185 
186  while (true) {
187  if (pthread_mutex_lock(&(s->CounterMutex)) != 0) std::cerr << "pthread_mutex_lock failed\n";
188  for (uint32 core = 0; core < s->m->getNumCores(); ++core) {
189  s->cstates1[core] = std::move(s->cstates2[core]);
190  s->cstates2[core] = s->m->getCoreCounterState(core);
191  }
192 
193  for (uint32 socket = 0; socket < s->m->getNumSockets(); ++socket) {
194  s->skstates1[socket] = std::move(s->skstates2[socket]);
195  s->skstates2[socket] = s->m->getSocketCounterState(socket);
196  }
197 
198  s->sstate1 = std::move(s->sstate2);
199  s->sstate2 = s->m->getSystemCounterState();
200 
201  if (pthread_mutex_unlock(&(s->CounterMutex)) != 0) std::cerr << "pthread_mutex_unlock failed\n";
202  sleep(1);
203  }
204  return NULL;
205 }
206 
207 #endif
uint32 getNumCores() const
Reads number of logical cores in the system.
Definition: cpucounters.cpp:5448
Definition: memoptest.cpp:24
uint64 getQPILinksPerSocket() const
Returns the number of Intel(r) Quick Path Interconnect(tm) links per socket.
Definition: cpucounters.h:1457
SystemCounterState getSystemCounterState()
Reads the counter state of the system.
Definition: cpucounters.cpp:4957
(Logical) core-wide counter state
Definition: cpucounters.h:2925
CoreCounterState getCoreCounterState(uint32 core)
Reads the counter state of a (logical) core.
Definition: cpucounters.cpp:5441
Socket-wide counter state.
Definition: cpucounters.h:2938
Definition: cpuasynchcounter.h:26
ErrorCode
Return codes (e.g. for program(..) method)
Definition: cpucounters.h:697
CPU Performance Monitor.
Definition: cpucounters.h:543
static PCM * getInstance()
Returns PCM object.
Definition: cpucounters.cpp:239
Main CPU counters header.
Definition: bw.cpp:12
SocketCounterState getSocketCounterState(uint32 socket)
Reads the counter state of a socket.
Definition: cpucounters.cpp:5315
System-wide counter state.
Definition: cpucounters.h:2978
uint32 getNumSockets() const
Reads number of sockets (CPUs) in the system.
Definition: cpucounters.cpp:5458
SocketCounterState getSocketCounterState(uint32 socket)
Reads the counter state of a socket.
Definition: cpucounters.cpp:4240
CoreCounterState getCoreCounterState(uint32 core)
Reads the counter state of a (logical) core.
Definition: cpucounters.cpp:4248
int32 getSocketId(uint32 core_id) const
Determines socket of given core.
Definition: cpucounters.h:1453
void cleanup(const bool silent=false)
Cleanups resources and stops performance counting.
Definition: cpucounters.cpp:4112