cisst-saw
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
osaStopwatch.h
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ex: set filetype=cpp softtabstop=4 shiftwidth=4 tabstop=4 cindent expandtab: */
3 
4 /*
5  Author(s): Ofri Sadowsky, Min Yang Jung
6  Created on: 2005-02-17
7 
8  (C) Copyright 2005-2014 Johns Hopkins University (JHU), All Rights Reserved.
9 
10 --- begin cisst license - do not edit ---
11 
12 This software is provided "as is" under an open source license, with
13 no warranty. The complete license can be found in license.txt and
14 http://www.cisst.org/cisst/license.txt.
15 
16 --- end cisst license ---
17 */
18 
19 
20 #ifndef _osaStopwatch_h
21 #define _osaStopwatch_h
22 
23 #include <iostream>
25 #include <cisstCommon/cmnUnits.h>
26 #include <cisstCommon/cmnLogger.h>
27 
28 #if (CISST_OS == CISST_WINDOWS) || (CISST_OS == CISST_CYGWIN)
29  #include <Windows.h>
30 #elif (CISST_OS == CISST_QNX)
31  #include <time.h>
32  #ifndef timersub
33  #define timersub(a, b, res) \
34  do { \
35  (res)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
36  (res)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; \
37  if ((res)->tv_nsec < 0) \
38  { \
39  (res)->tv_sec--; \
40  (res)->tv_nsec += 1000000000L; \
41  } \
42  } while (0)
43  #endif /*timersub*/
44 
45 #elif (CISST_OS == CISST_LINUX_XENOMAI)
46 
47 #include <native/timer.h>
48 
49 #elif (CISST_OS == CISST_LINUX_RTAI) || (CISST_OS == CISST_LINUX) || (CISST_OS == CISST_DARWIN) || (CISST_OS == CISST_SOLARIS)
50  #include <sys/time.h>
51  #if (CISST_OS == CISST_SOLARIS) || (CISST_COMPILER == CISST_GCC)
52  #ifndef timersub
53  #define timersub(a, b, res) \
54  do { \
55  (res)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
56  (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
57  if ((res)->tv_usec < 0) \
58  { \
59  (res)->tv_sec--; \
60  (res)->tv_usec += 1000000; \
61  } \
62  } while (0)
63  #endif /*timersub*/
64  #endif
65 #endif // CISST_OS == CISST_SOLARIS
66 
67 
68 // Always include last
70 
83 {
84 public:
85  typedef unsigned long MillisecondsCounter;
86  typedef double SecondsCounter;
87 
89 #if (CISST_OS == CISST_WINDOWS) || (CISST_OS == CISST_CYGWIN)
90  :
91  HasHighPerformanceCounter(false)
92 #endif
93  {
94 #if (CISST_OS == CISST_WINDOWS) || (CISST_OS == CISST_CYGWIN)
95  static LARGE_INTEGER frequency = { 0, 0 };
96  HasHighPerformanceCounter = (::QueryPerformanceFrequency( &frequency )) ? true : false;
97  if (HasHighPerformanceCounter) {
98  this->TimeGranularity = 1.0 / static_cast<double>(frequency.QuadPart); // this value should be in seconds
99  CMN_LOG_INIT_WARNING << "Class osaStopwatch: Can use HighPerformance Counter, time granularity is: "
100  << TimeGranularity * cmn_ms << " ms" << std::endl;
101  } else {
102  this->TimeGranularity = 1.0e-3; // 1 millisecond
103  CMN_LOG_INIT_WARNING << "Class osaStopwatch: Can NOT use HighPerformance Counter, time granularity is about: "
104  << TimeGranularity * cmn_ms << " ms" << std::endl;
105  }
106 
107 #elif (CISST_OS == CISST_LINUX_XENOMAI)
108 
109  this->TimeGranularity = 1.0e-9; // 1 microsecond
110 #elif (CISST_OS == CISST_LINUX_RTAI) || (CISST_OS == CISST_LINUX) || (CISST_OS == CISST_DARWIN) || (CISST_OS == CISST_SOLARIS) || (CISST_OS == CISST_QNX)
111  this->TimeGranularity = 1.0e-6; // 1 microsecond
112 #endif
113  Reset();
114  }
115 
118  double CISST_EXPORT GetTimeGranularity(void) const;
119 
121  void Reset(void)
122  {
123  RunningFlag = false;
124  AccumulatedTime = 0;
125 #if (CISST_OS == CISST_WINDOWS) || (CISST_OS == CISST_CYGWIN)
126  StartTicks = 0;
127 #elif (CISST_OS == CISST_LINUX_XENOMAI)
128 
129  StartTicks = 0;
130 
131 #elif (CISST_OS == CISST_LINUX_RTAI) || (CISST_OS == CISST_LINUX) || (CISST_OS == CISST_DARWIN) || (CISST_OS == CISST_SOLARIS)
132  StartTimeOfDay.tv_sec = 0;
133  StartTimeOfDay.tv_usec = 0;
134 #elif (CISST_OS == CISST_QNX)
135  StartTimeOfDay.tv_sec = 0;
136  StartTimeOfDay.tv_nsec = 0;
137 #endif
138  }
139 
142  inline void Start(void)
143  {
144  if (IsRunning()) {
145  return;
146  }
147 
148 #if (CISST_OS == CISST_WINDOWS) || (CISST_OS == CISST_CYGWIN)
149  if (HasHighPerformanceCounter) {
150  LARGE_INTEGER ticks;
151  ::QueryPerformanceCounter(&ticks);
152  StartTicks = GetTimeGranularity() * static_cast<double>(ticks.QuadPart);
153  }
154  else {
155  StartTicks = ::GetTickCount();
156  }
157 
158 #elif (CISST_OS == CISST_LINUX_XENOMAI)
159 
160  StartTicks = rt_timer_read();
161 
162 #elif (CISST_OS == CISST_LINUX_RTAI) || (CISST_OS == CISST_LINUX) || (CISST_OS == CISST_DARWIN) || (CISST_OS == CISST_SOLARIS)
163  gettimeofday(&StartTimeOfDay, 0);
164 #elif (CISST_OS == CISST_QNX)
165  if (clock_gettime(CLOCK_REALTIME, &StartTimeOfDay) == -1) {
166  CMN_LOG_INIT_ERROR << "Stopwatch start failed" << std::endl;
167  }
168 #endif
169  RunningFlag = true;
170  }
171 
172 
174  inline void Stop(void)
175  {
176  if (!IsRunning())
177  return;
178  RunningFlag = false;
179  AccumulatedTime += GetLastTimeInterval();
180  }
181 
182 
186  inline bool IsRunning(void) const
187  {
188  return RunningFlag;
189  }
190 
191 
197  {
198  if (!IsRunning()) {
199  return static_cast<MillisecondsCounter>(AccumulatedTime * 1000.0);
200  }
201  return static_cast<MillisecondsCounter>((AccumulatedTime + GetLastTimeInterval()) * 1000.0);
202  }
203 
207  inline SecondsCounter GetElapsedTime(void) const
208  {
209  if (!IsRunning()) {
210  return AccumulatedTime;
211  }
212  return AccumulatedTime + GetLastTimeInterval();
213  }
214 
215 private:
216 
217  inline SecondsCounter GetLastTimeInterval(void) const
218  {
219 #if (CISST_OS == CISST_WINDOWS) || (CISST_OS == CISST_CYGWIN)
220  SecondsCounter endTicks;
221  SecondsCounter totalSeconds;
222  if (HasHighPerformanceCounter) {
223  LARGE_INTEGER ticks;
224  QueryPerformanceCounter(&ticks);
225  endTicks = GetTimeGranularity() * static_cast<double>(ticks.QuadPart);
226  totalSeconds = endTicks - StartTicks;
227  } else {
228  endTicks = ::GetTickCount();
229  totalSeconds = static_cast<double>(endTicks - StartTicks) / 1000.0;
230  }
231 #elif (CISST_OS == CISST_LINUX_XENOMAI)
232 
233  SecondsCounter totalSeconds = (rt_timer_read() - StartTicks) * cmn_ns;
234 
235 #elif (CISST_OS == CISST_LINUX_RTAI) || (CISST_OS == CISST_LINUX) || (CISST_OS == CISST_DARWIN) || (CISST_OS == CISST_SOLARIS)
236  timeval endTimeOfDay;
237  timeval diffTime;
238  gettimeofday(&endTimeOfDay, 0);
239  timersub(&endTimeOfDay, &StartTimeOfDay, &diffTime);
240  SecondsCounter totalSeconds = diffTime.tv_sec + diffTime.tv_usec / 1000000.0;
241 #elif (CISST_OS == CISST_QNX)
242  struct timespec endTimeOfDay;
243  struct timespec diffTime;
244  SecondsCounter totalSeconds = 0;
245  if (clock_gettime(CLOCK_REALTIME, &endTimeOfDay) == -1) {
246  CMN_LOG_RUN_ERROR << "GetLastTimeInterval failed" << std::endl;
247  } else {
248  timersub(&endTimeOfDay, &StartTimeOfDay, &diffTime);
249  totalSeconds = diffTime.tv_sec + diffTime.tv_nsec * cmn_ns;
250  }
251 #endif
252  return totalSeconds;
253  }
254 
255  bool RunningFlag;
256  SecondsCounter AccumulatedTime;
257 
258 #if (CISST_OS == CISST_WINDOWS) || (CISST_OS == CISST_CYGWIN)
259  bool HasHighPerformanceCounter;
260 #endif
261  double TimeGranularity;
262 
263 #if (CISST_OS == CISST_WINDOWS) || (CISST_OS == CISST_CYGWIN)
264  SecondsCounter StartTicks;
265 #elif (CISST_OS == CISST_LINUX_XENOMAI)
266 
267  RTIME StartTicks;
268 
269 #elif (CISST_OS == CISST_LINUX_RTAI) || (CISST_OS == CISST_LINUX) || (CISST_OS == CISST_DARWIN) || (CISST_OS == CISST_SOLARIS)
270  timeval StartTimeOfDay;
271 #elif (CISST_OS == CISST_QNX)
272  struct timespec StartTimeOfDay;
273 #endif
274 
275 };
276 
277 
278 #endif // _osaStopwatch_h
279 
#define CISST_EXPORT
Definition: cmnExportMacros.h:50
#define CISST_DEPRECATED
Definition: cmnPortability.h:310
#define CMN_LOG_RUN_ERROR
Definition: cmnLogger.h:166
void Reset(void)
Definition: osaStopwatch.h:121
unsigned long MillisecondsCounter
Definition: osaStopwatch.h:85
Portability across compilers and operating systems tools.
MillisecondsCounter CISST_DEPRECATED GetCurrentRead(void) const
Definition: osaStopwatch.h:196
bool IsRunning(void) const
Definition: osaStopwatch.h:186
#define CMN_LOG_INIT_ERROR
Definition: cmnLogger.h:162
Declaration of units and unit conversion methodsThis file include the definition and implementation o...
Declaration of cmnLogger amd macros for human readable logging.
SecondsCounter GetElapsedTime(void) const
Definition: osaStopwatch.h:207
Definition: osaStopwatch.h:82
Macros to export the symbols of cisstOSAbstraction (in a Dll).
const double cmn_ms
Definition: cmnUnits.h:190
void Stop(void)
Definition: osaStopwatch.h:174
const double cmn_ns
Definition: cmnUnits.h:208
double CISST_EXPORT GetTimeGranularity(void) const
osaStopwatch(void)
Definition: osaStopwatch.h:88
#define CMN_LOG_INIT_WARNING
Definition: cmnLogger.h:163
double SecondsCounter
Definition: osaStopwatch.h:86
void Start(void)
Definition: osaStopwatch.h:142