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)
92 typedef boost::int_fast64_t int64_type;
94 /** \brief Absolute time data type
96 <a href="http://www.boost.org/doc/libs/release/libs/date_time/index.html">Boost.DateTime</a>
97 datatype used to represent absolute date/time values.
99 typedef boost::posix_time::ptime abstime_type;
101 /** \brief Relative time data type
103 <a href="http://www.boost.org/doc/libs/release/libs/date_time/index.html">Boost.DateTime</a>
104 datatype used to represent time intervals
106 typedef boost::posix_time::time_duration reltime_type;
108 //-////////////////////////////////////////////////////////////////////////
110 static clock_type now(); ///< Return current clock value
112 static abstime_type abstime(clock_type clock); ///< Convert clock to absolute time
113 /**< This member converts a clock value into an absolute
114 <a href="http://www.boost.org/doc/libs/release/libs/date_time/index.html">Boost.DateTime</a>
116 \note You should not base timeout calculations on this
117 absolute time value. Clock time is guaranteed to be
118 monotonous, absolute time may be non-monotonous if
119 the system date/time is changed. */
121 static reltime_type reltime(clock_type clock); ///< Convert clock to relative time
122 /**< This member converts a clock value into a relative
123 <a href="http://www.boost.org/doc/libs/release/libs/date_time/index.html">Boost.DateTime</a>
125 \note The resolution of reltime_type might be smaller
126 than the clock_type resolution */
128 static clock_type clock(abstime_type time); ///< Convert absolute time to clock value
129 /**< This member convert an absolute time value into the
130 corresponding clock value.
133 static clock_type from_time_t(time_t const & time);
134 ///< Convert legacy time_t to clock value
135 /**< This member converts an absolute time value
136 represented as a time_t value into a clock value */
138 static clock_type from_timeval(timeval const & time);
139 ///< Convert legacy timeval to clock value
140 /**< This member converts an absolute time value
141 represented as a timeval value into a clock value */
143 static clock_type nanoseconds(int64_type v); ///< Convert \a v nanoseconds to clock_type
144 static clock_type microseconds(int64_type v); ///< Convert \a v microseconds to clock_type
145 static clock_type milliseconds(int64_type v); ///< Convert \a v milliseconds to clock_type
146 static clock_type seconds(int64_type v); ///< Convert \a v seconds to clock_type
147 static clock_type minutes(int64_type v); ///< Convert \a v minutes to clock_type
148 static clock_type hours(int64_type v); ///< Convert \a v hours to clock_type
149 static clock_type days(int64_type v); ///< Convert \a v days to clock_type
151 static int64_type in_nanoseconds(clock_type v); ///< Convert \a v to nanoseconds
152 static int64_type in_microseconds(clock_type v); ///< Convert \a v to microseconds
153 static int64_type in_milliseconds(clock_type v); ///< Convert \a v to milliseconds
154 static int64_type in_seconds(clock_type v); ///< Convert \a v to seconds
155 static int64_type in_minutes(clock_type v); ///< Convert \a v to minutes
156 static int64_type in_hours(clock_type v); ///< Convert \a v to hours
157 static int64_type in_days(clock_type v); ///< Convert \a v to days
159 static void restart(); ///< Force re-synchronization of abstime and clock
160 /**< Calling the member should never be necessary since
161 abstime() / clock() automatically call restart() if
167 abstime_type abstime_m(clock_type clock);
168 clock_type clock_m(abstime_type time);
171 boost::posix_time::ptime baseAbstime_;
172 clock_type baseClock_;
174 /// Internal: ClockService private data (PIMPL idiom)
177 friend class singleton<ClockService>;
181 /** \brief Console argument parser to parse value as time interval
183 This parser will parse a time interval specification into a ClockService::clock_type
184 value. The following units are supported:
186 <table class="senf fixedcolumn">
187 <tr><td>\c d</td><td>days</td></tr>
188 <tr><td>\c h</td><td>hours</td></tr>
189 <tr><td>\c m</td><td>minutes</td></tr>
190 <tr><td>\c s</td><td>seconds</td></tr>
193 Additionally, the unit may be prefixed by an SI scale:
195 <table class="senf fixedcolumn">
196 <tr><td>\c m</td><td>milli</td></tr>
197 <tr><td>\c u</td><td>micro</td></tr>
198 <tr><td>\c n</td><td>nano</td></tr>
201 An optional decimal point is also supported. A single timer interval may combine any number
202 of these specifications. The following are all valid intervals:
204 <table class="senf fixedcolumn">
205 <tr><td><code>10d</code></td><td>10 days</td></tr>
206 <tr><td><code>5d5d</code></td><td>10 days</td></tr>
207 <tr><td><code>1d2h100m3.5s</code></td><td>27 hours, 30 minutes and 3.5 seconds</td></tr>
208 <tr><td><code>1s100ms</code></td><td>1.1 seconds</td></tr>
209 <tr><td><code>1.1s</code></td><td>1.1 seconds</td></tr>
210 <tr><td><code>123.456us</code></td><td>123.456 microseconds</td></tr>
211 <tr><td><code>2md</code></td><td>(very unusual) 2 milli-days</td></tr>
214 void parseClockServiceInterval(console::ParseCommandInfo::TokensRange const & tokens,
215 ClockService::clock_type & out);
217 void formatClockServiceInterval(ClockService::clock_type interval, std::ostream & os);
220 //-/////////////////////////////////////////////////////////////////////////////////////////////////
221 #include "ClockService.cci"
222 //#include "ClockService.ct"
223 //#include "ClockService.cti"
230 // comment-column: 40
231 // c-file-style: "senf"
232 // indent-tabs-mode: nil
233 // ispell-local-dictionary: "american"
234 // compile-command: "scons -u test"