Visual Servoing Platform version 3.5.0
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
68namespace vpTime
69{
70#endif
71
79static const double minTimeForUsleepCall = 4;
80
86double getMinTimeForUsleepCall() { return minTimeForUsleepCall; }
87
93double measureTimeMicros()
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
126double measureTimeMs()
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
158double measureTimeSecond() { return vpTime::measureTimeMs() * 1e-3; }
159
173int 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
224void 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
271void 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
358std::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
377vpChrono::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
409void 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}
void start(bool reset=true)
Definition: vpTime.cpp:409
void stop()
Definition: vpTime.cpp:424
double getDurationSeconds()
Definition: vpTime.cpp:400
vpChrono()
Definition: vpTime.cpp:377
double getDurationMs()
Definition: vpTime.cpp:392
double getDurationMicros()
Definition: vpTime.cpp:384
error that can be emited by ViSP classes.
Definition: vpException.h:72
@ functionNotImplementedError
Function not implemented.
Definition: vpException.h:90
@ fatalError
Fatal error.
Definition: vpException.h:96
Time management and measurement.
Definition: vpTime.h:79
VISP_EXPORT int wait(double t0, double t)
VISP_EXPORT double measureTimeMicros()
VISP_EXPORT double getMinTimeForUsleepCall()
VISP_EXPORT double measureTimeSecond()
VISP_EXPORT void sleepMs(double t)
VISP_EXPORT std::string getDateTime(const std::string &format="%Y/%m/%d %H:%M:%S")
VISP_EXPORT double measureTimeMs()