4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief ClockService public header */
26 #ifndef HH_SENF_Scheduler_ClockService_
27 #define HH_SENF_Scheduler_ClockService_ 1
31 #include <boost/utility.hpp>
32 #include <boost/date_time/posix_time/posix_time.hpp>
33 #include <boost/scoped_ptr.hpp>
34 #include <boost/cstdint.hpp>
35 #include "../Utils/singleton.hh"
36 #include "Console/Parse.hh"
38 //#include "ClockService.mpp"
39 ///////////////////////////////hh.p////////////////////////////////////////
44 namespace detail { class ClockServiceTest; }
47 // Implementation note: The clock value is represented as a 64bit unsigned integer number of
48 // nanosecods based on the CLOCK_MONOTONIC POSIX clock.
50 // To allow conversion between clock value and absolute time, the ClockService samples the
51 // absolute current time and the clock value when the conversion is performed. This is done at
52 // most once per second on a if-needed basis.
54 /** \brief Reliable high precision monotonous clock source
56 The ClockService provides a highly accurate monotonous clock source based on
57 gettimeofday(). However, it takes additional precautions to detect clock skew.
59 \implementation The funny mixture of static and non-static members stems from the old
60 implementation based on interval timers and gettimeofday(). The current implementation
61 usses POSIX clocks and is much simpler and more precise.
64 : singleton<ClockService>
67 ///////////////////////////////////////////////////////////////////////////
70 /** \brief ClockService timer data type
72 Unsigned integer type representing scheduler time. Scheduler time is measured in
73 nanoseconds relative to some implementation defined reference time.
75 typedef boost::int_fast64_t clock_type;
77 /** \brief Supplementary integer type
79 This type is used to represent varies supplementary values (e.g. number of microseconds)
81 typedef boost::int_fast64_t int64_type;
83 /** \brief Absolute time data type
85 Boost.DateTime datatype used to represent absolute date/time values.
87 typedef boost::posix_time::ptime abstime_type;
89 /** \brief Relative time data type
91 Boost.DateTime datatype used to represent time intervals
93 typedef boost::posix_time::time_duration reltime_type;
95 ///////////////////////////////////////////////////////////////////////////
97 static clock_type now(); ///< Return current clock value
99 static abstime_type abstime(clock_type clock); ///< Convert clock to absolute time
100 /**< This member converts a clock value into an absolute
101 Boost.DateTime value.
102 \note You should not base timeout calculations on this
103 absolute time value. Clock time is guaranteed to be
104 monotonous, absolute time may be non-monotonous if
105 the system date/time is changed. */
107 static reltime_type reltime(clock_type clock); ///< Convert clock to relative time
108 /**< This member converts a clock value into a relative
109 Boost.DateTime time interval
110 \note The resolution of reltime_type might be smaller
111 than the clock_type resolution */
113 static clock_type clock(abstime_type time); ///< Convert absolute time to clock value
114 /**< This member converst an absolute time value into the
115 corresponding clock value.
118 static clock_type from_time_t(time_t const & time);
119 ///< Convert legacy time_t to clock value
120 /**< This member converts an absolute time value
121 represented as a time_t value into a clock value */
123 static clock_type from_timeval(timeval const & time);
124 ///< Convert legacy timeval to clock value
125 /**< This member converts an absolute time value
126 represented as a timeval value into a clock value */
128 static clock_type nanoseconds(int64_type v); ///< Convert \a v nanoseconds to clock_type
129 static clock_type microseconds(int64_type v); ///< Convert \a v microseconds to clock_type
130 static clock_type milliseconds(int64_type v); ///< Convert \a v milliseconds to clock_type
131 static clock_type seconds(int64_type v); ///< Convert \a v seconds to clock_type
132 static clock_type minutes(int64_type v); ///< Convert \a v minutes to clock_type
133 static clock_type hours(int64_type v); ///< Convert \a v hours to clock_type
134 static clock_type days(int64_type v); ///< Convert \a v days to clock_type
136 static int64_type in_nanoseconds(clock_type v); ///< Convert \a v to nanoseconds
137 static int64_type in_microseconds(clock_type v); ///< Convert \a v to microseconds
138 static int64_type in_milliseconds(clock_type v); ///< Convert \a v to milliseconds
139 static int64_type in_seconds(clock_type v); ///< Convert \a v to seconds
140 static int64_type in_minutes(clock_type v); ///< Convert \a v to minutes
141 static int64_type in_hours(clock_type v); ///< Convert \a v to hours
142 static int64_type in_days(clock_type v); ///< Convert \a v to days
144 static void restart(); ///< Force re-syncronisation of abstime and clock
145 /**< Calling the member should never be necessary since
146 abstime() / clock() automatically call restart() if
152 abstime_type abstime_m(clock_type clock);
153 clock_type clock_m(abstime_type time);
156 boost::posix_time::ptime baseAbstime_;
157 clock_type baseClock_;
159 /// Internal: ClockService private data (PIMPL idiom)
162 friend class singleton<ClockService>;
166 /** \brief Console argument parser to parse value as time interval
168 This parser will parse a time interval specification into a ClockService::clock_type
169 value. The following units are supported:
171 <table class="senf fixedcolumn">
172 <tr><td>\c d</td><td>days</td></tr>
173 <tr><td>\c h</td><td>hours</td></tr>
174 <tr><td>\c m</td><td>minutes</td></tr>
175 <tr><td>\c s</td><td>seconds</td></tr>
178 Additionally, the unit may be prefixed by an SI scale:
180 <table class="senf fixedcolumn">
181 <tr><td>\c m</td><td>milli</td></tr>
182 <tr><td>\c u</td><td>micro</td></tr>
183 <tr><td>\c n</td><td>nano</td></tr>
186 An optional decimal point is also supported. A single timer interval may combine any number
187 of these specifications. The following are all valid intervals:
189 <table class="senf fixedcolumn">
190 <tr><td><code>10d</code></td><td>10 days</td></tr>
191 <tr><td><code>5d5d</code></td><td>10 days</td></tr>
192 <tr><td><code>1d2h100m3.5s</code></td><td>27 hours, 30 minutes and 3.5 seconds</td></tr>
193 <tr><td><code>1s100ms</code></td><td>1.1 seconds</td></tr>
194 <tr><td><code>1.1s</code></td><td>1.1 seconds</td></tr>
195 <tr><td><code>123.456us</code></td><td>123.456 microseconds</td></tr>
196 <tr><td><code>2md</code></td><td>(very unusual) 2 milli-days</td></tr>
199 void parseClockServiceInterval(console::ParseCommandInfo::TokensRange const & tokens,
200 ClockService::clock_type & out);
203 ///////////////////////////////hh.e////////////////////////////////////////
204 #include "ClockService.cci"
205 //#include "ClockService.ct"
206 //#include "ClockService.cti"
213 // comment-column: 40
214 // c-file-style: "senf"
215 // indent-tabs-mode: nil
216 // ispell-local-dictionary: "american"
217 // compile-command: "scons -u test"