Utils/Console: Fix singleton instantiation order (ServerManager / Scheduler)
[senf.git] / Scheduler / ClockService.hh
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief ClockService public header */
25
26 #ifndef HH_ClockService_
27 #define HH_ClockService_ 1
28
29 // Custom includes
30 #include <sys/time.h> 
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
37 //#include "ClockService.mpp"
38 ///////////////////////////////hh.p////////////////////////////////////////
39
40 namespace senf {
41
42 #ifndef DOXYGEN
43     namespace detail { class ClockServiceTest; }
44 #endif
45
46     // Implementation note: The clock value is represented as a 64bit unsigned integer number of
47     // nanosecods based on the CLOCK_MONOTONIC POSIX clock.
48     //
49     // To allow conversion between clock value and absolute time, the ClockService samples the
50     // absolute current time and the clock value when the conversion is performed. This is done at
51     // most once per second on a if-needed basis.
52     
53     /** \brief Reliable high precision monotonous clock source
54
55         The ClockService provides a highly accurate monotonous clock source based on
56         gettimeofday(). However, it takes additional precautions to detect clock skew.
57
58         \implementation The funny mixture of static and non-static members stems from the old
59             implementation based on interval timers and gettimeofday(). The current implementation
60             usses POSIX clocks and is much simpler and more precise.
61       */
62     class ClockService
63         : singleton<ClockService>
64     {
65     public:
66         ///////////////////////////////////////////////////////////////////////////
67         // Types
68
69         /** \brief ClockService timer data type
70             
71             Unsigned integer type representing scheduler time. Scheduler time is measured in
72             nanoseconds relative to some implementation defined reference time.
73          */
74         typedef boost::int_fast64_t clock_type;
75
76         /** \brief Supplementary integer type
77
78             This type is used to represent varies supplementary values (e.g. number of microseconds)
79          */
80         typedef boost::int_fast64_t int64_type;
81
82         /** \brief Absolute time data type
83
84             Boost.DateTime datatype used to represent absolute date/time values.
85          */
86         typedef boost::posix_time::ptime abstime_type;
87
88         ///////////////////////////////////////////////////////////////////////////
89
90         static clock_type now();  ///< Return current clock value
91         
92         static abstime_type abstime(clock_type clock); ///< Convert clock to absolute time
93                                         /**< This member converts a clock value into an absolute
94                                              Boost.DateTime value.
95                                              \note You should not base timeout calculations on this
96                                                  absolute time value. Clock time is guaranteed to be
97                                                  monotonous, absolute time may be non-monotonous if
98                                                  the system date/time is changed. */
99
100         static clock_type clock(abstime_type time); ///< Convert absolute time to clock value
101                                         /**< This member converst an absolute time value into the
102                                              corresponding clock value.
103                                              \see abstime */
104
105         static clock_type from_time_t(time_t const & time); 
106                                         ///< Convert legacy time_t to clock value
107                                         /**< This member converts an absolute time value 
108                                              represented as a time_t value into a clock value */
109
110         static clock_type from_timeval(timeval const & time); 
111                                         ///< Convert legacy timeval to clock value
112                                         /**< This member converts an absolute time value
113                                              represented as a timeval value into a clock value */
114
115         static clock_type nanoseconds(int64_type v); ///< Convert \a v nanoseconds to clock_type
116         static clock_type microseconds(int64_type v); ///< Convert \a v microseconds to clock_type
117         static clock_type milliseconds(int64_type v); ///< Convert \a v milliseconds to clock_type
118         static clock_type seconds(int64_type v); ///< Convert \a v seconds to clock_type
119         static clock_type minutes(int64_type v); ///< Convert \a v minutes to clock_type
120         static clock_type hours(int64_type v); ///< Convert \a v hours to clock_type
121         static clock_type days(int64_type v); ///< Convert \a v days to clock_type
122
123         static int64_type in_nanoseconds(clock_type v); ///< Convert \a v to nanoseconds
124         static int64_type in_microseconds(clock_type v); ///< Convert \a v to microseconds
125         static int64_type in_milliseconds(clock_type v); ///< Convert \a v to milliseconds
126         static int64_type in_seconds(clock_type v); ///< Convert \a v to seconds
127         static int64_type in_minutes(clock_type v); ///< Convert \a v to minutes
128         static int64_type in_hours(clock_type v); ///< Convert \a v to hours
129         static int64_type in_days(clock_type v); ///< Convert \a v to days
130
131         static void restart(); ///< Force re-syncronisation of abstime and clock
132                                         /**< Calling the member should never be necessary since
133                                              abstime() / clock() automatically call restart() if
134                                              needed */
135
136     private:
137         ClockService();
138
139         abstime_type abstime_m(clock_type clock);
140         clock_type clock_m(abstime_type time);
141         void restart_m();
142
143         boost::posix_time::ptime baseAbstime_;
144         clock_type baseClock_;
145
146         /// Internal: ClockService private data (PIMPL idiom)
147
148 #ifndef DOXYGEN
149         friend class singleton<ClockService>;
150 #endif
151     };
152
153 }
154
155 ///////////////////////////////hh.e////////////////////////////////////////
156 #include "ClockService.cci"
157 //#include "ClockService.ct"
158 //#include "ClockService.cti"
159 #endif
160
161 \f
162 // Local Variables:
163 // mode: c++
164 // fill-column: 100
165 // comment-column: 40
166 // c-file-style: "senf"
167 // indent-tabs-mode: nil
168 // ispell-local-dictionary: "american"
169 // compile-command: "scons -u test"
170 // End: