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 <senf/config.hh>
36 #include <senf/Utils/singleton.hh>
37 #include <senf/Utils/Console/Parse.hh>
39 //#include "ClockService.mpp"
40 ///////////////////////////////hh.p////////////////////////////////////////
45 namespace detail { class ClockServiceTest; }
48 // Implementation note: The clock value is represented as a 64bit unsigned integer number of
49 // nanoseconds based on the CLOCK_MONOTONIC POSIX clock.
51 // To allow conversion between clock value and absolute time, the ClockService samples the
52 // absolute current time and the clock value when the conversion is performed. This is done at
53 // most once per second on a if-needed basis.
55 /** \brief Reliable high precision monotonous clock source
57 The ClockService provides a highly accurate monotonous clock source based on
58 gettimeofday(). However, it takes additional precautions to detect clock skew.
60 \implementation The funny mixture of static and non-static members stems from the old
61 implementation based on interval timers and gettimeofday(). The current implementation
62 uses POSIX clocks and is much simpler and more precise.
65 : singleton<ClockService>
68 ///////////////////////////////////////////////////////////////////////////
71 /** \brief ClockService timer data type
73 Unsigned integer type representing scheduler time. Scheduler time is measured in
74 nanoseconds relative to some implementation defined reference time.
76 typedef config::time_type clock_type;
78 /** \brief Supplementary integer type
80 This type is used to represent varies supplementary values (e.g. number of microseconds)
82 typedef boost::int_fast64_t int64_type;
84 /** \brief Absolute time data type
86 <a href="http://www.boost.org/doc/libs/release/libs/date_time/index.html">Boost.DateTime</a>
87 datatype used to represent absolute date/time values.
89 typedef boost::posix_time::ptime abstime_type;
91 /** \brief Relative time data type
93 <a href="http://www.boost.org/doc/libs/release/libs/date_time/index.html">Boost.DateTime</a>
94 datatype used to represent time intervals
96 typedef boost::posix_time::time_duration reltime_type;
98 ///////////////////////////////////////////////////////////////////////////
100 static clock_type now(); ///< Return current clock value
102 static abstime_type abstime(clock_type clock); ///< Convert clock to absolute time
103 /**< This member converts a clock value into an absolute
104 <a href="http://www.boost.org/doc/libs/release/libs/date_time/index.html">Boost.DateTime</a>
106 \note You should not base timeout calculations on this
107 absolute time value. Clock time is guaranteed to be
108 monotonous, absolute time may be non-monotonous if
109 the system date/time is changed. */
111 static reltime_type reltime(clock_type clock); ///< Convert clock to relative time
112 /**< This member converts a clock value into a relative
113 <a href="http://www.boost.org/doc/libs/release/libs/date_time/index.html">Boost.DateTime</a>
115 \note The resolution of reltime_type might be smaller
116 than the clock_type resolution */
118 static clock_type clock(abstime_type time); ///< Convert absolute time to clock value
119 /**< This member convert an absolute time value into the
120 corresponding clock value.
123 static clock_type from_time_t(time_t const & time);
124 ///< Convert legacy time_t to clock value
125 /**< This member converts an absolute time value
126 represented as a time_t value into a clock value */
128 static clock_type from_timeval(timeval const & time);
129 ///< Convert legacy timeval to clock value
130 /**< This member converts an absolute time value
131 represented as a timeval value into a clock value */
133 static clock_type nanoseconds(int64_type v); ///< Convert \a v nanoseconds to clock_type
134 static clock_type microseconds(int64_type v); ///< Convert \a v microseconds to clock_type
135 static clock_type milliseconds(int64_type v); ///< Convert \a v milliseconds to clock_type
136 static clock_type seconds(int64_type v); ///< Convert \a v seconds to clock_type
137 static clock_type minutes(int64_type v); ///< Convert \a v minutes to clock_type
138 static clock_type hours(int64_type v); ///< Convert \a v hours to clock_type
139 static clock_type days(int64_type v); ///< Convert \a v days to clock_type
141 static int64_type in_nanoseconds(clock_type v); ///< Convert \a v to nanoseconds
142 static int64_type in_microseconds(clock_type v); ///< Convert \a v to microseconds
143 static int64_type in_milliseconds(clock_type v); ///< Convert \a v to milliseconds
144 static int64_type in_seconds(clock_type v); ///< Convert \a v to seconds
145 static int64_type in_minutes(clock_type v); ///< Convert \a v to minutes
146 static int64_type in_hours(clock_type v); ///< Convert \a v to hours
147 static int64_type in_days(clock_type v); ///< Convert \a v to days
149 static void restart(); ///< Force re-synchronization of abstime and clock
150 /**< Calling the member should never be necessary since
151 abstime() / clock() automatically call restart() if
157 abstime_type abstime_m(clock_type clock);
158 clock_type clock_m(abstime_type time);
161 boost::posix_time::ptime baseAbstime_;
162 clock_type baseClock_;
164 /// Internal: ClockService private data (PIMPL idiom)
167 friend class singleton<ClockService>;
171 /** \brief Console argument parser to parse value as time interval
173 This parser will parse a time interval specification into a ClockService::clock_type
174 value. The following units are supported:
176 <table class="senf fixedcolumn">
177 <tr><td>\c d</td><td>days</td></tr>
178 <tr><td>\c h</td><td>hours</td></tr>
179 <tr><td>\c m</td><td>minutes</td></tr>
180 <tr><td>\c s</td><td>seconds</td></tr>
183 Additionally, the unit may be prefixed by an SI scale:
185 <table class="senf fixedcolumn">
186 <tr><td>\c m</td><td>milli</td></tr>
187 <tr><td>\c u</td><td>micro</td></tr>
188 <tr><td>\c n</td><td>nano</td></tr>
191 An optional decimal point is also supported. A single timer interval may combine any number
192 of these specifications. The following are all valid intervals:
194 <table class="senf fixedcolumn">
195 <tr><td><code>10d</code></td><td>10 days</td></tr>
196 <tr><td><code>5d5d</code></td><td>10 days</td></tr>
197 <tr><td><code>1d2h100m3.5s</code></td><td>27 hours, 30 minutes and 3.5 seconds</td></tr>
198 <tr><td><code>1s100ms</code></td><td>1.1 seconds</td></tr>
199 <tr><td><code>1.1s</code></td><td>1.1 seconds</td></tr>
200 <tr><td><code>123.456us</code></td><td>123.456 microseconds</td></tr>
201 <tr><td><code>2md</code></td><td>(very unusual) 2 milli-days</td></tr>
204 void parseClockServiceInterval(console::ParseCommandInfo::TokensRange const & tokens,
205 ClockService::clock_type & out);
207 void formatClockServiceInterval(ClockService::clock_type interval, std::ostream & os);
210 ///////////////////////////////hh.e////////////////////////////////////////
211 #include "ClockService.cci"
212 //#include "ClockService.ct"
213 //#include "ClockService.cti"
220 // comment-column: 40
221 // c-file-style: "senf"
222 // indent-tabs-mode: nil
223 // ispell-local-dictionary: "american"
224 // compile-command: "scons -u test"