libqi-api
2.0.6.8
|
00001 /* 00002 * Copyright (c) 2013 Aldebaran Robotics. All rights reserved. 00003 * Use of this source code is governed by a BSD-style license that can be 00004 * found in the COPYING file. 00005 */ 00006 00007 #pragma once 00008 #ifndef _QI_CLOCK_HPP_ 00009 #define _QI_CLOCK_HPP_ 00010 00011 #include <qi/api.hpp> 00012 #include <qi/types.hpp> 00013 #include <boost/chrono.hpp> 00014 00015 namespace qi 00016 { 00017 00018 00019 typedef boost::chrono::duration<int64_t, boost::nano> Duration; 00020 typedef boost::chrono::duration<int64_t, boost::nano> NanoSeconds; 00021 typedef boost::chrono::duration<int64_t, boost::micro> MicroSeconds; 00022 typedef boost::chrono::duration<int64_t, boost::milli> MilliSeconds; 00023 typedef boost::chrono::duration<int64_t> Seconds; 00024 typedef boost::chrono::duration<int64_t, boost::ratio<60> > Minutes; 00025 typedef boost::chrono::duration<int64_t, boost::ratio<3600> > Hours; 00026 00027 00028 class QI_API SteadyClock 00029 { 00030 public: 00031 typedef int64_t rep; 00032 typedef boost::nano period; // clock counts nanoseconds 00033 typedef boost::chrono::duration<rep, period> duration; 00034 typedef boost::chrono::time_point<SteadyClock> time_point; 00035 BOOST_STATIC_CONSTEXPR bool is_steady = boost::chrono::steady_clock::is_steady; 00036 00037 public: 00038 typedef boost::chrono::time_point<SteadyClock> SteadyClockTimePoint; 00039 00040 enum Expect { 00041 Expect_SoonerOrLater, 00042 Expect_Later, 00043 Expect_Sooner 00044 }; 00045 00046 00047 // Returns a time_point representing the current value of the clock. 00048 static SteadyClockTimePoint now(); 00049 00050 // Convert the time point to a number of milliseconds on 32 bits. 00051 // Since the 32 bits number overflows every 2^32 ms ~ 50 days, 00052 // this is a lossy operation. 00053 static uint32_t toUint32ms(const SteadyClockTimePoint &t) throw(); 00054 static int32_t toInt32ms(const SteadyClockTimePoint &t) throw(); 00055 00056 // Get a time point from a number of milliseconds on 32 bits. 00057 // 00058 // Since the 32 bits number overflows every ~50 days, an infinity of 00059 // time points match a given 32 bits number (all modulo ~50 days). 00060 // This function picks the result near the guess timepoint depending on 00061 // the expect argument: 00062 // 00063 // if expect == LATER, result is expected to be later than guess: 00064 // 00065 // guess <= result < guess + period 00066 // 00067 // if expect == SOONER, result is expected to be sooner than guess: 00068 // 00069 // guess - period < result <= guess 00070 // 00071 // if expect == SOONER_OR_LATER, pick the nearest result: 00072 // 00073 // guess - period/2 < result <= guess + period/2 00074 // 00075 // where period == 2^32 ms ~ 50 days 00076 static time_point fromUint32ms(uint32_t t_ms, SteadyClockTimePoint guess, 00077 Expect expect=Expect_SoonerOrLater) throw(); 00078 static time_point fromInt32ms(int32_t t_ms, SteadyClockTimePoint guess, 00079 Expect expect=Expect_SoonerOrLater) throw(); 00080 }; 00081 00082 class QI_API WallClock 00083 { 00084 public: 00085 typedef int64_t rep; 00086 typedef boost::nano period; // clock counts nanoseconds 00087 typedef boost::chrono::duration<rep, period> duration; 00088 typedef boost::chrono::time_point<WallClock> time_point; 00089 BOOST_STATIC_CONSTEXPR bool is_steady = false; 00090 00091 public: 00092 typedef boost::chrono::time_point<WallClock> WallClockTimePoint; 00093 00094 // Returns a time_point representing the current value of the clock. 00095 static WallClockTimePoint now(); 00096 00097 // Converts a system clock time point to std::time_t 00098 static std::time_t to_time_t(const WallClockTimePoint& t) throw(); 00099 00100 // Converts std::time_t to a system clock time point 00101 static WallClockTimePoint from_time_t(const std::time_t &t) throw(); 00102 }; 00103 00104 00105 00106 typedef SteadyClock::SteadyClockTimePoint SteadyClockTimePoint; 00107 typedef WallClock::WallClockTimePoint WallClockTimePoint; 00108 00109 inline SteadyClockTimePoint steadyClockNow() { 00110 return SteadyClock::now(); 00111 } 00112 00113 inline WallClockTimePoint wallClockNow() { 00114 return WallClock::now(); 00115 } 00116 00117 00118 // Blocks the execution of the current thread for at least d. 00119 QI_API void sleepFor(const qi::Duration& d); 00120 template <class Rep, class Period> 00121 inline void sleepFor(const boost::chrono::duration<Rep, Period>& d); 00122 00123 // Blocks the execution of the current thread until t has been 00124 // reached. 00125 // 00126 // This is equivalent to sleep_for(t-steady_clock::now()) 00127 QI_API void sleepUntil(const SteadyClockTimePoint &t); 00128 template <class Duration> 00129 inline void sleepUntil(const boost::chrono::time_point<SteadyClock, Duration>& t); 00130 00131 // Blocks the execution of the current thread until t has been 00132 // reached. 00133 // Adjustments of the clock are taken into account. 00134 // Thus the duration of the block might, but might not, be less 00135 // or more than t - system_clock::now() 00136 QI_API void sleepUntil(const WallClockTimePoint& t); 00137 template <class Duration> 00138 inline void sleepUntil(const boost::chrono::time_point<WallClock, Duration>& t); 00139 00140 } 00141 00142 #ifdef __APPLE__ 00143 //export template instanciation for RTTI issues across libraries. (mostly for OSX) 00144 template class QI_API boost::chrono::duration<int64_t, boost::nano>; 00145 template class QI_API boost::chrono::duration<int64_t, boost::micro>; 00146 template class QI_API boost::chrono::duration<int64_t, boost::milli>; 00147 template class QI_API boost::chrono::duration<int64_t>; 00148 template class QI_API boost::chrono::duration<int64_t, boost::ratio<60> >; 00149 template class QI_API boost::chrono::duration<int64_t, boost::ratio<3600> >; 00150 template class QI_API boost::chrono::time_point<qi::SteadyClock>; 00151 template class QI_API boost::chrono::time_point<qi::WallClock>; 00152 #endif 00153 00154 #include <qi/clock.hxx> 00155 00156 #endif // _QI_OS_HPP_