ClockService.hh
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #ifndef HH_SENF_Scheduler_ClockService_
18 #define HH_SENF_Scheduler_ClockService_ 1
19 
20 // Custom includes
21 #include <boost/date_time/posix_time/posix_time.hpp>
22 #include <senf/config.hh>
23 #include <senf/Utils/singleton.hh>
25 
26 #ifdef SENF_DEBUG
28 #endif
29 
30 #ifdef SENF_DEBUG
31 # define SENF_CLOCKSERVICE_CONSTEXPR
32 #else
33 # ifdef SENF_CXX11_ENABLED
34 # define SENF_CLOCKSERVICE_CONSTEXPR constexpr
35 # else
36 # define SENF_CLOCKSERVICE_CONSTEXPR
37 # endif
38 #endif
39 
40 //-/////////////////////////////////////////////////////////////////////////////////////////////////
41 
42 namespace senf {
43 
44  // Implementation note: The clock value is represented as a 64bit unsigned integer number of
45  // nanoseconds based on the CLOCK_MONOTONIC POSIX clock.
46  //
47  // To allow conversion between clock value and absolute time, the ClockService samples the
48  // absolute current time and the clock value when the conversion is performed. This is done at
49  // most once per second on a if-needed basis.
50 
60 // namespace scheduler { ClockService::clock_type now(); }
61 
63  : singleton<ClockService>
64  {
65  public:
66  //-////////////////////////////////////////////////////////////////////////
67  // Types
68 
74 #ifdef SENF_DEBUG
75  struct ClockTypeTag {};
77 #else
78  typedef config::time_type clock_type;
79 #endif
80 
84  typedef std::int64_t int64_type;
85 
91  typedef boost::posix_time::ptime abstime_type;
92 
98  typedef boost::posix_time::time_duration reltime_type;
99 
100  //-////////////////////////////////////////////////////////////////////////
101 
102  static constexpr clock_type maxTime = std::numeric_limits<config::time_type>::max();
103 
104  static clock_type now();
105 
106  static abstime_type abstime(clock_type const & clock);
107 
115  static reltime_type reltime(clock_type const & clock);
116 
122  static clock_type clock(abstime_type const & time);
123 
127  static clock_type from_time_t(time_t const & time);
129 
132  static time_t to_time_t(clock_type const & time);
134 
137  static clock_type from_timeval(timeval const & time);
139 
142  static SENF_CLOCKSERVICE_CONSTEXPR clock_type nanoseconds(int64_type const & v);
143  static SENF_CLOCKSERVICE_CONSTEXPR clock_type microseconds(int64_type const & v);
144  static SENF_CLOCKSERVICE_CONSTEXPR clock_type milliseconds(int64_type const & v);
145  static SENF_CLOCKSERVICE_CONSTEXPR clock_type seconds(int64_type const & v);
146  static SENF_CLOCKSERVICE_CONSTEXPR clock_type minutes(int64_type const & v);
147  static SENF_CLOCKSERVICE_CONSTEXPR clock_type hours(int64_type const & v);
148  static SENF_CLOCKSERVICE_CONSTEXPR clock_type days(int64_type const & v);
149 
150  static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_nanoseconds(clock_type const & v);
151  static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_microseconds(clock_type const & v);
152  static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_milliseconds(clock_type const & v);
153  static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_seconds(clock_type const & v);
154  static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_minutes(clock_type const & v);
155  static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_hours(clock_type const & v);
156  static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_days(clock_type const & v);
157 
158  static void restart();
159 
163  private:
164  ClockService();
165 
166  abstime_type abstime_m(clock_type const & clock);
167  clock_type clock_m(abstime_type const & time);
168  void restart_m();
169 
170  boost::posix_time::ptime baseAbstime_;
171  clock_type baseClock_;
172 
173  friend class singleton<ClockService>;
174  };
175 
211 
212  void formatClockServiceInterval(ClockService::clock_type interval, std::ostream & os);
213 
214  class CyclicTimestamp final
215  {
216  public:
218  : tstamp_(0) {
219  }
220  CyclicTimestamp(std::uint32_t const & secs, std::uint32_t const & nsecs) {
221  update(secs, nsecs);
222  }
223 
224  void update(ClockService::clock_type const & clockType) {
225  tstamp_ = std::uint32_t(std::uint64_t(senf::ClockService::in_milliseconds(clockType)) % 0x100000000ull);
226  }
227 
228  void update(std::uint32_t const & secs, std::uint32_t const & nsecs) {
229  tstamp_ = (secs * 1000) + (nsecs / 1000000);
230  }
231 
232  std::uint32_t const & value() const {
233  return tstamp_;
234  }
235 
236  CyclicTimestamp distance(CyclicTimestamp const & other) const {
237  return CyclicTimestamp(other.tstamp_ - tstamp_);
238  }
239 
240  std::uint32_t distanceAsMilliseconds(CyclicTimestamp const & other) const {
241  return other.tstamp_ - tstamp_;
242  }
243 
245  return senf::ClockService::milliseconds(distanceAsMilliseconds(other));
246  }
247 
248  private:
249  CyclicTimestamp(std::uint32_t && value)
250  :tstamp_(value) {
251  }
252 
253  std::uint32_t tstamp_;
254  };
255 }
256 
257 //-/////////////////////////////////////////////////////////////////////////////////////////////////
258 #include "ClockService.cci"
259 //#include "ClockService.ct"
260 //#include "ClockService.cti"
261 #endif
262 
263 
264 // Local Variables:
265 // mode: c++
266 // fill-column: 100
267 // comment-column: 40
268 // c-file-style: "senf"
269 // indent-tabs-mode: nil
270 // ispell-local-dictionary: "american"
271 // compile-command: "scons -u test"
272 // End:
config::time_type clock_type
ClockService timer data type.
Definition: ClockService.hh:78
static clock_type from_time_t(time_t const &time)
Convert legacy time_t to clock value.
static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_milliseconds(clock_type const &v)
Convert v to milliseconds.
static SENF_CLOCKSERVICE_CONSTEXPR clock_type days(int64_type const &v)
Convert v days to clock_type.
boost::posix_time::time_duration reltime_type
Relative time data type.
Definition: ClockService.hh:98
static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_hours(clock_type const &v)
Convert v to hours.
static SENF_CLOCKSERVICE_CONSTEXPR clock_type hours(int64_type const &v)
Convert v hours to clock_type.
static SENF_CLOCKSERVICE_CONSTEXPR clock_type seconds(int64_type const &v)
Convert v seconds to clock_type.
CyclicTimestamp(std::uint32_t const &secs, std::uint32_t const &nsecs)
Reliable high precision monotonous clock source.
Definition: ClockService.hh:62
std::uint32_t const & value() const
static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_microseconds(clock_type const &v)
Convert v to microseconds.
static constexpr clock_type maxTime
static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_days(clock_type const &v)
Convert v to days.
static time_t to_time_t(clock_type const &time)
Convert legacy time_t to clock value to legacy time_t.
static SENF_CLOCKSERVICE_CONSTEXPR clock_type milliseconds(int64_type const &v)
Convert v milliseconds to clock_type.
static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_nanoseconds(clock_type const &v)
Convert v to nanoseconds.
static reltime_type reltime(clock_type const &clock)
Convert clock to relative time.
void update(std::uint32_t const &secs, std::uint32_t const &nsecs)
senf::ClockService::clock_type distanceAsClockType(CyclicTimestamp const &other) const
static SENF_CLOCKSERVICE_CONSTEXPR clock_type microseconds(int64_type const &v)
Convert v microseconds to clock_type.
void formatClockServiceInterval(ClockService::clock_type interval, std::ostream &os)
#define SENF_CLOCKSERVICE_CONSTEXPR
Definition: ClockService.hh:36
static abstime_type abstime(clock_type const &clock)
Convert clock to absolute time.
static void restart()
Force re-synchronization of abstime and clock.
std::int64_t int64_type
Supplementary integer type.
Definition: ClockService.hh:84
boost::iterator_range< token_iterator > TokensRange
boost::posix_time::ptime abstime_type
Absolute time data type.
Definition: ClockService.hh:91
void parseClockServiceInterval(console::ParseCommandInfo::TokensRange const &tokens, ClockService::clock_type &out)
Console argument parser to parse value as time interval.
Definition: ClockService.cc:82
static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_minutes(clock_type const &v)
Convert v to minutes.
static clock_type now()
Return current clock value.
static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_seconds(clock_type const &v)
Convert v to seconds.
std::uint32_t distanceAsMilliseconds(CyclicTimestamp const &other) const
void update(ClockService::clock_type const &clockType)
static clock_type from_timeval(timeval const &time)
Convert legacy timeval to clock value.
static SENF_CLOCKSERVICE_CONSTEXPR clock_type minutes(int64_type const &v)
Convert v minutes to clock_type.
CyclicTimestamp distance(CyclicTimestamp const &other) const
static clock_type clock(abstime_type const &time)
Convert absolute time to clock value.
static SENF_CLOCKSERVICE_CONSTEXPR clock_type nanoseconds(int64_type const &v)
Convert v nanoseconds to clock_type.