4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief ClockService public header */
31 #ifndef HH_SENF_Scheduler_ClockService_
32 #define HH_SENF_Scheduler_ClockService_ 1
36 #include <boost/utility.hpp>
37 #include <boost/date_time/posix_time/posix_time.hpp>
38 #include <boost/scoped_ptr.hpp>
39 #include <boost/cstdint.hpp>
40 #include <senf/config.hh>
41 #include <senf/Utils/singleton.hh>
42 #include <senf/Utils/Console/Parse.hh>
43 #include <senf/Utils/RestrictedInt.hh>
45 //#include "ClockService.mpp"
46 //-/////////////////////////////////////////////////////////////////////////////////////////////////
51 namespace detail { class ClockServiceTest; }
54 // Implementation note: The clock value is represented as a 64bit unsigned integer number of
55 // nanoseconds based on the CLOCK_MONOTONIC POSIX clock.
57 // To allow conversion between clock value and absolute time, the ClockService samples the
58 // absolute current time and the clock value when the conversion is performed. This is done at
59 // most once per second on a if-needed basis.
61 /** \brief Reliable high precision monotonous clock source
63 The ClockService provides a highly accurate monotonous clock source based on
64 gettimeofday(). However, it takes additional precautions to detect clock skew.
66 \implementation The funny mixture of static and non-static members stems from the old
67 implementation based on interval timers and gettimeofday(). The current implementation
68 uses POSIX clocks and is much simpler and more precise.
71 : singleton<ClockService>
74 //-////////////////////////////////////////////////////////////////////////
77 /** \brief ClockService timer data type
79 Unsigned integer type representing scheduler time. Scheduler time is measured in
80 nanoseconds relative to some implementation defined reference time.
83 struct ClockTypeTag {};
84 typedef senf::RestrictedInt<config::time_type, ClockTypeTag> clock_type;
86 typedef config::time_type clock_type;
88 /** \brief Supplementary integer type
90 This type is used to represent varies supplementary values (e.g. number of microseconds)
93 typedef boost::int_fast64_t int64_type;
95 /** \brief Absolute time data type
97 <a href="http://www.boost.org/doc/libs/release/libs/date_time/index.html">Boost.DateTime</a>
98 datatype used to represent absolute date/time values.
100 typedef boost::posix_time::ptime abstime_type;
102 /** \brief Relative time data type
104 <a href="http://www.boost.org/doc/libs/release/libs/date_time/index.html">Boost.DateTime</a>
105 datatype used to represent time intervals
107 typedef boost::posix_time::time_duration reltime_type;
109 //-////////////////////////////////////////////////////////////////////////
111 static clock_type now(); ///< Return current clock value
113 static abstime_type abstime(clock_type clock); ///< Convert clock to absolute time
114 /**< This member converts a clock value into an absolute
115 <a href="http://www.boost.org/doc/libs/release/libs/date_time/index.html">Boost.DateTime</a>
117 \note You should not base timeout calculations on this
118 absolute time value. Clock time is guaranteed to be
119 monotonous, absolute time may be non-monotonous if
120 the system date/time is changed. */
122 static reltime_type reltime(clock_type clock); ///< Convert clock to relative time
123 /**< This member converts a clock value into a relative
124 <a href="http://www.boost.org/doc/libs/release/libs/date_time/index.html">Boost.DateTime</a>
126 \note The resolution of reltime_type might be smaller
127 than the clock_type resolution */
129 static clock_type clock(abstime_type time); ///< Convert absolute time to clock value
130 /**< This member convert an absolute time value into the
131 corresponding clock value.
134 static clock_type from_time_t(time_t const & time);
135 ///< Convert legacy time_t to clock value
136 /**< This member converts an absolute time value
137 represented as a time_t value into a clock value */
139 static clock_type from_timeval(timeval const & time);
140 ///< Convert legacy timeval to clock value
141 /**< This member converts an absolute time value
142 represented as a timeval value into a clock value */
144 static clock_type nanoseconds(int64_type v); ///< Convert \a v nanoseconds to clock_type
145 static clock_type microseconds(int64_type v); ///< Convert \a v microseconds to clock_type
146 static clock_type milliseconds(int64_type v); ///< Convert \a v milliseconds to clock_type
147 static clock_type seconds(int64_type v); ///< Convert \a v seconds to clock_type
148 static clock_type minutes(int64_type v); ///< Convert \a v minutes to clock_type
149 static clock_type hours(int64_type v); ///< Convert \a v hours to clock_type
150 static clock_type days(int64_type v); ///< Convert \a v days to clock_type
152 static int64_type in_nanoseconds(clock_type v); ///< Convert \a v to nanoseconds
153 static int64_type in_microseconds(clock_type v); ///< Convert \a v to microseconds
154 static int64_type in_milliseconds(clock_type v); ///< Convert \a v to milliseconds
155 static int64_type in_seconds(clock_type v); ///< Convert \a v to seconds
156 static int64_type in_minutes(clock_type v); ///< Convert \a v to minutes
157 static int64_type in_hours(clock_type v); ///< Convert \a v to hours
158 static int64_type in_days(clock_type v); ///< Convert \a v to days
160 static void restart(); ///< Force re-synchronization of abstime and clock
161 /**< Calling the member should never be necessary since
162 abstime() / clock() automatically call restart() if
168 abstime_type abstime_m(clock_type clock);
169 clock_type clock_m(abstime_type time);
172 boost::posix_time::ptime baseAbstime_;
173 clock_type baseClock_;
175 /// Internal: ClockService private data (PIMPL idiom)
178 friend class singleton<ClockService>;
182 /** \brief Console argument parser to parse value as time interval
184 This parser will parse a time interval specification into a ClockService::clock_type
185 value. The following units are supported:
187 <table class="senf fixedcolumn">
188 <tr><td>\c d</td><td>days</td></tr>
189 <tr><td>\c h</td><td>hours</td></tr>
190 <tr><td>\c m</td><td>minutes</td></tr>
191 <tr><td>\c s</td><td>seconds</td></tr>
194 Additionally, the unit may be prefixed by an SI scale:
196 <table class="senf fixedcolumn">
197 <tr><td>\c m</td><td>milli</td></tr>
198 <tr><td>\c u</td><td>micro</td></tr>
199 <tr><td>\c n</td><td>nano</td></tr>
202 An optional decimal point is also supported. A single timer interval may combine any number
203 of these specifications. The following are all valid intervals:
205 <table class="senf fixedcolumn">
206 <tr><td><code>10d</code></td><td>10 days</td></tr>
207 <tr><td><code>5d5d</code></td><td>10 days</td></tr>
208 <tr><td><code>1d2h100m3.5s</code></td><td>27 hours, 30 minutes and 3.5 seconds</td></tr>
209 <tr><td><code>1s100ms</code></td><td>1.1 seconds</td></tr>
210 <tr><td><code>1.1s</code></td><td>1.1 seconds</td></tr>
211 <tr><td><code>123.456us</code></td><td>123.456 microseconds</td></tr>
212 <tr><td><code>2md</code></td><td>(very unusual) 2 milli-days</td></tr>
215 void parseClockServiceInterval(console::ParseCommandInfo::TokensRange const & tokens,
216 ClockService::clock_type & out);
218 void formatClockServiceInterval(ClockService::clock_type interval, std::ostream & os);
221 //-/////////////////////////////////////////////////////////////////////////////////////////////////
222 #include "ClockService.cci"
223 //#include "ClockService.ct"
224 //#include "ClockService.cti"
231 // comment-column: 40
232 // c-file-style: "senf"
233 // indent-tabs-mode: nil
234 // ispell-local-dictionary: "american"
235 // compile-command: "scons -u test"