Intel(r) Performance Counter Monitor
width_extender.h
Go to the documentation of this file.
1 /*
2 Copyright (c) 2009-2012, Intel Corporation
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 
7  * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9  * Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10 
11 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12 */
13 // written by Roman Dementiev
14 // Austen Ott
15 
16 #ifndef WIDTH_EXTENDER_HEADER_
17 #define WIDTH_EXTENDER_HEADER_
18 
23 #ifdef _MSC_VER
24 #include <windows.h>
25 #else
26 #include <pthread.h>
27 #endif
28 
29 #include <stdlib.h>
30 #include "cpucounters.h"
31 #include "client_bw.h"
32 
33 #ifdef _MSC_VER
34 DWORD WINAPI WatchDogProc(LPVOID state);
35 #else
36 void * WatchDogProc(void * state);
37 #endif
38 
40 {
41 public:
43  {
44  virtual uint64 operator() () = 0;
45  virtual ~AbstractRawCounter() {}
46  };
47 
49  {
50  SafeMsrHandle * msr;
51  uint64 msr_addr;
52  MsrHandleCounter(SafeMsrHandle * msr_, uint64 msr_addr_): msr(msr_), msr_addr(msr_addr_) {}
53  uint64 operator() ()
54  {
55  uint64 value = 0;
56  msr->read(msr_addr,&value);
57  return value;
58  }
59  };
60 
62  {
63  ClientBW * clientBW;
64  ClientImcReadsCounter(ClientBW * clientBW_): clientBW(clientBW_) {}
65  uint64 operator() () { return clientBW->getImcReads(); }
66  };
67 
69  {
70  ClientBW * clientBW;
71  ClientImcWritesCounter(ClientBW * clientBW_): clientBW(clientBW_) {}
72  uint64 operator() () { return clientBW->getImcWrites(); }
73  };
74 
76  {
77  ClientBW * clientBW;
78  ClientIoRequestsCounter(ClientBW * clientBW_): clientBW(clientBW_) {}
79  uint64 operator() () { return clientBW->getIoRequests(); }
80  };
81 
82 private:
83 
84 #ifdef _MSC_VER
85  HANDLE UpdateThread;
86  HANDLE CounterMutex;
87 #else
88  pthread_t UpdateThread;
89  pthread_mutex_t CounterMutex;
90 #endif
91 
92  AbstractRawCounter * raw_counter;
93  uint64 extended_value;
94  uint64 last_raw_value;
95 
96  CounterWidthExtender(); // forbidden
98 
99  uint64 internal_read()
100  {
101  if (this==NULL) return 0; // to make security check happy
102  uint64 result = 0, new_raw_value = 0;
103 #ifdef _MSC_VER
104  WaitForSingleObject(CounterMutex,INFINITE);
105 #else
106  pthread_mutex_lock(&CounterMutex);
107 #endif
108  new_raw_value = (*raw_counter)();
109  if(new_raw_value < last_raw_value)
110  {
111  extended_value += ((1ULL<<32ULL)-last_raw_value) + new_raw_value;
112  }
113  else
114  {
115  extended_value += (new_raw_value-last_raw_value);
116  }
117 
118  last_raw_value = new_raw_value;
119 
120  result = extended_value;
121 #ifdef _MSC_VER
122  ReleaseMutex(CounterMutex);
123 #else
124  pthread_mutex_unlock(&CounterMutex);
125 #endif
126  return result;
127  }
128 
129 public:
130  CounterWidthExtender(AbstractRawCounter * raw_counter_): raw_counter(raw_counter_)
131  {
132  last_raw_value = (*raw_counter)();
133  extended_value = last_raw_value;
134 
135 #ifdef _MSC_VER
136  CounterMutex = CreateMutex(NULL,FALSE,NULL);
137  UpdateThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)WatchDogProc,this,0,NULL);
138 #else
139  pthread_mutex_init(&CounterMutex, NULL);
140  pthread_create(&UpdateThread, NULL, WatchDogProc, this);
141 #endif
142  }
144  {
145 #ifdef _MSC_VER
146  TerminateThread(UpdateThread,0);
147  CloseHandle(UpdateThread);
148  CloseHandle(CounterMutex);
149 #else
150  pthread_cancel(UpdateThread);
151  pthread_mutex_destroy(&CounterMutex);
152 #endif
153  if(raw_counter) delete raw_counter;
154  }
155 
156  uint64 read() // read extended value
157  {
158  return internal_read();
159  }
160 };
161 
162 
163 #endif
Definition: width_extender.h:42
Definition: width_extender.h:68
Interface to access client bandwidth counters.
Main CPU counters header.
Definition: width_extender.h:75
Definition: width_extender.h:39
Definition: client_bw.h:40
Definition: msr.h:62
Definition: width_extender.h:61
Definition: width_extender.h:48