StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Stopwatch.h
1 // @(#)root/base:$Name: $:$Id: Stopwatch.h,v 1.2 2016/06/21 03:39:45 smirnovd Exp $
2 // Author: Fons Rademakers 11/10/95
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #ifndef _Stopwatch
13 #define _Stopwatch
14 
15 
17 // //
18 // TStopwatch //
19 // //
20 // Stopwatch class. This class returns the real and cpu time between //
21 // the start and stop events. //
22 // //
24 
25 
26 class Stopwatch {
27 
28 private:
29  enum EState { kUndefined, kStopped, kRunning };
30 
31  double fStartRealTime; //wall clock start time
32  double fStopRealTime; //wall clock stop time
33  double fStartCpuTime; //cpu start time
34  double fStopCpuTime; //cpu stop time
35  double fTotalCpuTime; //total cpu time
36  double fTotalRealTime; //total real time
37  EState fState; //stopwatch state
38  int fCounter; //number of times the stopwatch was started
39 
40  inline static double GetRealTime();
41  inline static double GetCPUTime();
42 
43 public:
44  inline Stopwatch();
45  inline void Start(int reset = 1);
46  inline void Stop();
47  inline void Continue();
48  inline int Counter() const { return fCounter; }
49  inline double RealTime();
50  inline void Reset() { ResetCpuTime(); ResetRealTime(); }
51  inline void ResetCpuTime(double time = 0) { Stop(); fTotalCpuTime = time; }
52  inline void ResetRealTime(double time = 0) { Stop(); fTotalRealTime = time; }
53  inline double CpuTime();
54 };
55 
56 
57 //______________________________________________________________________________
58 
59 #ifndef _WIN32
60 #define R__UNIX
61 #endif
62 
63 #if defined(R__UNIX)
64 # include <sys/time.h>
65 # include <sys/times.h>
66 # include <unistd.h>
67 static double gTicks = 0;
68 #elif defined(R__VMS)
69 # include <time.h>
70 # include <unistd.h>
71 static double gTicks = 1000;
72 #elif defined(_WIN32)
73 # include <sys/types.h>
74 # include <sys/timeb.h>
75 # include <windows.h>
76 # undef min // unfortunately, <windows.h> defines min/max as macros
77 # undef max
78 //# include "TError.h"
79 const double gTicks = 1.0e-7;
80 static __int64 gTicksQPC = -1; // < 0 means "not yet initialized"
81 //# include "Windows4Root.h"
82 #endif
83 
84 
85 inline Stopwatch::Stopwatch():
86  fStartRealTime(0), fStopRealTime(0), fStartCpuTime(0), fStopCpuTime(0),
87  fTotalCpuTime(0), fTotalRealTime(0), fState(kUndefined), fCounter(0)
88 {
89  // Create a stopwatch and start it.
90 
91 #ifdef R__UNIX
92  if (!gTicks)
93  gTicks = (double)sysconf(_SC_CLK_TCK);
94 #endif
95 #ifdef _WIN32
96  if( gTicksQPC < 0 ) {
97  LARGE_INTEGER freq;
98  QueryPerformanceFrequency( &freq );
99  gTicksQPC = (double)freq.QuadPart;
100  }
101 #endif
102 
103  Start();
104 }
105 
106 //______________________________________________________________________________
107 inline void Stopwatch::Start(int reset)
108 {
109  // Start the stopwatch. If reset is kTRUE reset the stopwatch before
110  // starting it (including the stopwatch counter).
111  // Use kFALSE to continue timing after a Stop() without
112  // resetting the stopwatch.
113 
114  if (reset) {
115  fState = kUndefined;
116  fTotalCpuTime = 0;
117  fTotalRealTime = 0;
118  fCounter = 0;
119  }
120  if (fState != kRunning) {
121  fStartRealTime = GetRealTime();
122  fStartCpuTime = GetCPUTime();
123  }
124  fState = kRunning;
125  fCounter++;
126 }
127 
128 //______________________________________________________________________________
129 inline void Stopwatch::Stop()
130 {
131  // Stop the stopwatch.
132 
133  fStopRealTime = GetRealTime();
134  fStopCpuTime = GetCPUTime();
135 
136  if (fState == kRunning) {
137  fTotalCpuTime += fStopCpuTime - fStartCpuTime;
138  fTotalRealTime += fStopRealTime - fStartRealTime;
139  }
140  fState = kStopped;
141 }
142 
143 //______________________________________________________________________________
144 inline void Stopwatch::Continue()
145 {
146  // Resume a stopped stopwatch. The stopwatch continues counting from the last
147  // Start() onwards (this is like the laptimer function).
148 
149  if (fState == kUndefined){
150  //cout<< "stopwatch not started"<<endl;
151  return;
152  }
153  if (fState == kStopped) {
154  fTotalCpuTime -= fStopCpuTime - fStartCpuTime;
155  fTotalRealTime -= fStopRealTime - fStartRealTime;
156  }
157 
158  fState = kRunning;
159 }
160 
161 //______________________________________________________________________________
162 inline double Stopwatch::RealTime()
163 {
164  // Return the realtime passed between the start and stop events. If the
165  // stopwatch was still running stop it first.
166 
167  if (fState == kUndefined){
168  //cout<<"stopwatch not started"<<endl;
169  return 0;
170  }
171  if (fState == kRunning)
172  Stop();
173 
174  return fTotalRealTime;
175 }
176 
177 //______________________________________________________________________________
178 inline double Stopwatch::CpuTime()
179 {
180  // Return the cputime passed between the start and stop events. If the
181  // stopwatch was still running stop it first.
182 
183  if (fState == kUndefined){
184  //cout<<"stopwatch not started"<<endl;
185  return 0;
186  }
187  if (fState == kRunning)
188  Stop();
189 
190  return fTotalCpuTime;
191 }
192 
193 //______________________________________________________________________________
194 inline double Stopwatch::GetRealTime()
195 {
196 #if defined(R__UNIX)
197  struct timeval tp;
198  gettimeofday(&tp, 0);
199  return tp.tv_sec + (tp.tv_usec)*1.e-6;
200 #elif defined(_WIN32)
201  LARGE_INTEGER counter;
202  QueryPerformanceCounter( &counter );
203  return (double)counter.QuadPart / gTicksQPC;
204 #else
205  return 0;
206 #endif
207 }
208 
209 //______________________________________________________________________________
210 inline double Stopwatch::GetCPUTime()
211 {
212  // Private static method returning system CPU time.
213 
214 #if defined(R__UNIX)
215  struct tms cpt;
216  times(&cpt);
217  return (double)(cpt.tms_utime+cpt.tms_stime) / gTicks;
218 #elif defined(R__VMS)
219  return (double)clock() / gTicks;
220 #elif defined(_WIN32)
221  OSVERSIONINFO OsVersionInfo;
222 
223  // Value Platform
224  //----------------------------------------------------
225  // VER_PLATFORM_WIN32s Win32s on Windows 3.1
226  // VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95
227  // VER_PLATFORM_WIN32_NT Windows NT
228  //
229  OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
230  GetVersionEx(&OsVersionInfo);
231  if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
232  DWORD ret;
233  FILETIME ftCreate, // when the process was created
234  ftExit; // when the process exited
235 
236  union {
237  FILETIME ftFileTime;
238  __int64 ftInt64;
239  } ftKernel; // time the process has spent in kernel mode
240 
241  union {
242  FILETIME ftFileTime;
243  __int64 ftInt64;
244  } ftUser; // time the process has spent in user mode
245 
246  HANDLE hProcess = GetCurrentProcess();
247  ret = GetProcessTimes (hProcess, &ftCreate, &ftExit,
248  &ftKernel.ftFileTime,
249  &ftUser.ftFileTime);
250  if (ret != TRUE) {
251  ret = GetLastError ();
252  //cout<<" Error on GetProcessTimes 0x%lx"<<endl;
253  return 0;
254  }
255 
256  // Process times are returned in a 64-bit structure, as the number of
257  // 100 nanosecond ticks since 1 January 1601. User mode and kernel mode
258  // times for this process are in separate 64-bit structures.
259  // To convert to floating point seconds, we will:
260  //
261  // Convert sum of high 32-bit quantities to 64-bit int
262 
263  return (double) (ftKernel.ftInt64 + ftUser.ftInt64) * gTicks;
264  } else
265  return GetRealTime();
266 #endif
267 }
268 
269 #endif