X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Scheduler%2FClockService.hh;h=255fcbee9fae4edbbaa6770d632a12a9e2f2e014;hb=22e56fa8ef4cea3fd55c9463ecd2af8a6fbd213d;hp=3d5f40f554ba3e2cf0d8a8f27fb8d01663fcf3fd;hpb=3d16600678b948ff3bd0e4fd2a1a800fcc629a03;p=senf.git diff --git a/Scheduler/ClockService.hh b/Scheduler/ClockService.hh index 3d5f40f..255fcbe 100644 --- a/Scheduler/ClockService.hh +++ b/Scheduler/ClockService.hh @@ -1,8 +1,8 @@ // $Id$ // -// Copyright (C) 2007 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Copyright (C) 2007 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund // // This program is free software; you can redistribute it and/or modify @@ -27,9 +27,11 @@ #define HH_ClockService_ 1 // Custom includes +#include #include #include #include +#include "../Utils/singleton.hh" //#include "ClockService.mpp" ///////////////////////////////hh.p//////////////////////////////////////// @@ -64,22 +66,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. + + \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: /////////////////////////////////////////////////////////////////////////// @@ -90,7 +97,8 @@ 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; + typedef boost::int_fast64_t int64_type; /** \brief Absolute time data type @@ -98,7 +106,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 @@ -124,43 +132,65 @@ namespace senf { corresponding clock value. \see abstime */ - 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 clock_type from_time_t(time_t const & time); + ///< Convert legacy time_t to clock value + /**< This member converts an absolute time value + represented as a time_t value into a clock value */ + + static clock_type from_timeval(timeval const & time); + ///< Convert legacy timeval to clock value + /**< This member converts an absolute time value + represented as a timeval value into a clock value */ + + static clock_type nanoseconds(int64_type v); ///< Convert \a v nanoseconds to clock_type + static clock_type microseconds(int64_type v); ///< Convert \a v microseconds to clock_type + static clock_type milliseconds(int64_type v); ///< Convert \a v milliseconds to clock_type + static clock_type seconds(int64_type v); ///< Convert \a v seconds to clock_type + static clock_type minutes(int64_type v); ///< Convert \a v minutes to clock_type + static clock_type hours(int64_type v); ///< Convert \a v hours to clock_type + static clock_type days(int64_type v); ///< Convert \a v days to clock_type + + static int64_type in_nanoseconds(clock_type v); ///< Convert \a v to nanoseconds + static int64_type in_microseconds(clock_type v); ///< Convert \a v to microseconds + static int64_type in_milliseconds(clock_type v); ///< Convert \a v to milliseconds + static int64_type in_seconds(clock_type v); ///< Convert \a v to seconds + static int64_type in_minutes(clock_type v); ///< Convert \a v to minutes + static int64_type in_hours(clock_type v); ///< Convert \a v to hours + static int64_type in_days(clock_type v); ///< Convert \a v to days static void restart(); - protected: - private: - ClockService(); - static ClockService & instance(); - clock_type now_i(); - void restart_i(); + 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 clockSkew(boost::posix_time::ptime time, boost::posix_time::ptime expected); 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. + /// Internal: ClockService private data (PIMPL idiom) struct Impl; boost::scoped_ptr impl_; friend class Impl; #ifndef DOXYGEN friend class senf::detail::ClockServiceTest; + friend class singleton; #endif }; - } ///////////////////////////////hh.e////////////////////////////////////////