X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Scheduler%2FClockService.hh;h=d17eaf91ff1c1624fad8dc583fe092e3a19384bb;hb=f87667d7d3b3edafba7e67d6fc33168c4e1af620;hp=6ad51b5be9ca7395b3e2365bd1ae42c072fe1479;hpb=dd9cab12c8a33e57da1dd1104b530e8ea1591c53;p=senf.git diff --git a/Scheduler/ClockService.hh b/Scheduler/ClockService.hh index 6ad51b5..d17eaf9 100644 --- a/Scheduler/ClockService.hh +++ b/Scheduler/ClockService.hh @@ -28,13 +28,19 @@ // Custom includes #include -#include +#include +#include +#include "../Utils/singleton.hh" //#include "ClockService.mpp" ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { +#ifndef DOXYGEN + namespace detail { class ClockServiceTest; } +#endif + // Implementation note: // // The clock value is represented as a 64bit unsigned integer number of nanosecods elapsed since @@ -59,24 +65,27 @@ namespace senf { // amount the time has been changed. To do this we need an as accurate as possible approximation // of the expected current time value. We need to differentiate two cases: // - // a) Clock skew detected in within now() + // a) Clock skew detected within now() // - // In this case, we use getitimer() to find the time remaining in the timer. Using this value and - // an the saved gettimeofday() value we can adjust base_ accordingly. + // In this case, we use getitimer() to find the time remaining in the timer. Using this value + // and the saved gettimeofday() value we can adjust base_ accordingly. // // b) Clock skew detected in the signal handler // - // In this case we use the save gettimeofday() value + CheckInterval to adjust base_. + // In this case we use the saved gettimeofday() value + CheckInterval to adjust base_. /** \brief Reliable high precision monotonous clock source The ClockService provides a highly accurate monotonous clock source based on gettimeofday(). However, it takes additional precautions to detect clock skew. - \fixme Implement the clock-skew detection + \implementation We use a mix of static and non-static members to achieve high performance + in the normal case (no clock skew) and still encapsulate the dependency on legacy C + headers. Using the senf::singleton mixin ensures, that the instance is constructed + before main even when instance() is not called. */ class ClockService - : boost::noncopyable + : singleton { public: /////////////////////////////////////////////////////////////////////////// @@ -87,7 +96,7 @@ namespace senf { Unsigned integer type representing scheduler time. Scheduler time is measured in nanoseconds relative to some implementation defined reference time. */ - typedef boost::uint_fast64_t clock_type; + typedef boost::int_fast64_t clock_type; /** \brief Absolute time data type @@ -95,7 +104,7 @@ namespace senf { */ typedef boost::posix_time::ptime abstime_type; - static unsigned const CheckInterval = 1; + static unsigned const CheckInterval = 10; /////////////////////////////////////////////////////////////////////////// ///\name Structors and default members @@ -121,16 +130,45 @@ namespace senf { corresponding clock value. \see abstime */ - protected: + static clock_type nanoseconds(clock_type v); + static clock_type microseconds(clock_type v); + static clock_type milliseconds(clock_type v); + static clock_type seconds(clock_type v); + static clock_type minutes(clock_type v); + static clock_type hours(clock_type v); + static clock_type days(clock_type v); + + static void restart(); private: ClockService(); - static ClockService & instance(); - + void timer(); + + clock_type now_m(); + abstime_type abstime_m(clock_type clock); + clock_type clock_m(abstime_type time); + void restart_m(bool restart = true); + + bool checkSkew(boost::posix_time::ptime time); + void updateSkew(boost::posix_time::ptime time); + void clockSkew(boost::posix_time::ptime time, boost::posix_time::ptime expected); + + void restartTimer(bool restart = true); + boost::posix_time::ptime base_; - }; + boost::posix_time::ptime heartbeat_; + // I don't want this header to depend on the legacy C headers. + struct Impl; + boost::scoped_ptr impl_; + + friend class Impl; +#ifndef DOXYGEN + friend class senf::detail::ClockServiceTest; + friend class singleton; +#endif + }; }