Visual Servoing Platform  version 3.5.0 under development (2022-02-15)
vpTime.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Time management and measurement.
33  *
34  * Authors:
35  * Eric Marchand
36  * Fabien Spindler
37  *
38  *****************************************************************************/
39 
40 #include <ctime>
41 
42 #include <visp3/core/vpDebug.h>
43 #include <visp3/core/vpTime.h>
44 
45 //https://devblogs.microsoft.com/cppblog/c14-stl-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1/
46 #if VISP_CXX_STANDARD >= VISP_CXX_STANDARD_11 && (defined(_MSC_VER) && _MSC_VER >= 1900 /* VS2015 */ || !defined(_MSC_VER))
47 #define USE_CXX11_CHRONO 1
48 #else
49 #define USE_CXX11_CHRONO 0
50 #endif
51 
57 // Unix depend version
58 
59 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
60 #include <sys/time.h>
61 #include <unistd.h>
62 #elif defined(_WIN32)
63 //#include <winbase.h>
64 #include <windows.h>
65 #endif
66 
67 #ifndef DOXYGEN_SHOULD_SKIP_THIS
68 namespace vpTime
69 {
70 #endif
71 
79 static const double minTimeForUsleepCall = 4;
80 
86 double getMinTimeForUsleepCall() { return minTimeForUsleepCall; }
87 
94 {
95 #if USE_CXX11_CHRONO
96  std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
97  return std::chrono::duration<double, std::micro>(now.time_since_epoch()).count();
98 #else
99 #if defined(_WIN32)
100 #if !defined(WINRT)
101  LARGE_INTEGER time, frequency;
102  QueryPerformanceFrequency(&frequency);
103  if (frequency.QuadPart == 0) {
104  return (timeGetTime());
105  } else {
106  QueryPerformanceCounter(&time);
107  return (double)(1000000.0 * time.QuadPart / frequency.QuadPart);
108  }
109 #else
110  throw(vpException(vpException::fatalError, "Cannot get time: not implemented on Universal Windows Platform"));
111 #endif
112 #elif !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
113  struct timeval tp;
114  gettimeofday(&tp, 0);
115  return (1000000.0 * tp.tv_sec + tp.tv_usec);
116 #endif
117 #endif
118 }
119 
127 {
128 #if USE_CXX11_CHRONO
129  std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
130  return std::chrono::duration<double, std::milli>(now.time_since_epoch()).count();
131 #else
132 #if defined(_WIN32)
133 #if !defined(WINRT)
134  LARGE_INTEGER time, frequency;
135  QueryPerformanceFrequency(&frequency);
136  if (frequency.QuadPart == 0) {
137  return (timeGetTime());
138  } else {
139  QueryPerformanceCounter(&time);
140  return (double)(1000.0 * time.QuadPart / frequency.QuadPart);
141  }
142 #else
143  throw(vpException(vpException::fatalError, "Cannot get time: not implemented on Universal Windows Platform"));
144 #endif
145 #elif !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
146  struct timeval tp;
147  gettimeofday(&tp, 0);
148  return (1000.0 * tp.tv_sec + tp.tv_usec / 1000.0);
149 #endif
150 #endif
151 }
152 
158 double measureTimeSecond() { return vpTime::measureTimeMs() * 1e-3; }
159 
173 int wait(double t0, double t)
174 {
175  double timeCurrent, timeToWait;
176  timeCurrent = measureTimeMs();
177 
178  timeToWait = t0 + t - timeCurrent;
179 
180  if (timeToWait <= 0.) // no need to wait
181  return (1);
182  else {
183 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
184  if (timeToWait > vpTime::minTimeForUsleepCall) {
185  usleep((useconds_t)((timeToWait - vpTime::minTimeForUsleepCall) * 1000));
186  }
187  // Blocking loop to have an accurate waiting
188  do {
189  timeCurrent = measureTimeMs();
190  timeToWait = t0 + t - timeCurrent;
191 
192  } while (timeToWait > 0.);
193 
194  return 0;
195 #elif defined(_WIN32)
196 #if !defined(WINRT_8_0)
197  if (timeToWait > vpTime::minTimeForUsleepCall) {
198  Sleep((DWORD)(timeToWait - vpTime::minTimeForUsleepCall));
199  }
200  // Blocking loop to have an accurate waiting
201  do {
202  timeCurrent = measureTimeMs();
203  timeToWait = t0 + t - timeCurrent;
204 
205  } while (timeToWait > 0.);
206 
207  return 0;
208 #else
210  "vpTime::wait() is not implemented on Windows Phone 8.0"));
211 #endif
212 #endif
213  }
214 }
215 
224 void wait(double t)
225 {
226  double timeToWait = t;
227 
228  if (timeToWait <= 0.) // no need to wait
229  return;
230  else {
231 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
232  double t0 = measureTimeMs();
233  if (timeToWait > vpTime::minTimeForUsleepCall) {
234  usleep((useconds_t)((timeToWait - vpTime::minTimeForUsleepCall) * 1000));
235  }
236  // Blocking loop to have an accurate waiting
237  do {
238  double timeCurrent = measureTimeMs();
239  timeToWait = t0 + t - timeCurrent;
240 
241  } while (timeToWait > 0.);
242 
243  return;
244 #elif defined(_WIN32)
245 #if !defined(WINRT_8_0)
246  double t0 = measureTimeMs();
247  if (timeToWait > vpTime::minTimeForUsleepCall) {
248  Sleep((DWORD)(timeToWait - vpTime::minTimeForUsleepCall));
249  }
250  // Blocking loop to have an accurate waiting
251  do {
252  double timeCurrent = measureTimeMs();
253  timeToWait = t0 + t - timeCurrent;
254 
255  } while (timeToWait > 0.);
256 
257  return;
258 #else
260  "vpTime::wait() is not implemented on Windows Phone 8.0"));
261 #endif
262 #endif
263  }
264 }
265 
271 void sleepMs(double t)
272 {
273 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
274  usleep((useconds_t)(t * 1000));
275 #elif defined(_WIN32)
276 #if !defined(WINRT_8_0)
277  Sleep((DWORD)(t));
278 #else
280  "vpTime::sleepMs() is not implemented on Windows Phone 8.0"));
281 #endif
282 #endif
283 }
284 
358 std::string getDateTime(const std::string &format)
359 {
360  time_t rawtime;
361  struct tm *timeinfo;
362  char buffer[80];
363 
364  time(&rawtime);
365  timeinfo = localtime(&rawtime);
366 
367  strftime(buffer, 80, format.c_str(), timeinfo);
368  std::string str(buffer);
369 
370  return str;
371 }
372 
373 #ifndef DOXYGEN_SHOULD_SKIP_THIS
374 };
375 #endif
376 
377 vpChrono::vpChrono() : m_durationMs(), m_lastTimePoint()
378 {
379 }
380 
385 {
386  return m_durationMs * 1e3;
387 }
388 
393 {
394  return m_durationMs;
395 }
396 
401 {
402  return m_durationMs * 1e-3;
403 }
404 
409 void vpChrono::start(bool reset)
410 {
411 #if USE_CXX11_CHRONO
412  m_lastTimePoint = std::chrono::steady_clock::now();
413 #else
414  m_lastTimePoint = vpTime::measureTimeMs();
415 #endif
416  if (reset) {
417  m_durationMs = 0.0;
418  }
419 }
420 
425 {
426 #if USE_CXX11_CHRONO
427  m_durationMs += std::chrono::duration<double, std::milli>(std::chrono::steady_clock::now() - m_lastTimePoint).count();
428 #else
429  m_durationMs += vpTime::measureTimeMs() - m_lastTimePoint;
430 #endif
431 }
double getDurationMicros()
Definition: vpTime.cpp:384
vpChrono()
Definition: vpTime.cpp:377
VISP_EXPORT int wait(double t0, double t)
Definition: vpTime.cpp:173
double getDurationMs()
Definition: vpTime.cpp:392
Time management and measurement.
Definition: vpTime.h:78
VISP_EXPORT double measureTimeSecond()
Definition: vpTime.cpp:158
double getDurationSeconds()
Definition: vpTime.cpp:400
error that can be emited by ViSP classes.
Definition: vpException.h:71
VISP_EXPORT double measureTimeMs()
Definition: vpTime.cpp:126
VISP_EXPORT std::string getDateTime(const std::string &format="%Y/%m/%d %H:%M:%S")
Definition: vpTime.cpp:358
void start(bool reset=true)
Definition: vpTime.cpp:409
void stop()
Definition: vpTime.cpp:424
VISP_EXPORT void sleepMs(double t)
Definition: vpTime.cpp:271
VISP_EXPORT double measureTimeMicros()
Definition: vpTime.cpp:93
VISP_EXPORT double getMinTimeForUsleepCall()
Definition: vpTime.cpp:86
Function not implemented.
Definition: vpException.h:90