X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Scheduler%2FClockService.cc;h=7754f4c2380efe67f3b4532bc2720025e23b9162;hb=a1fdb7bb122f0b05be809a922d4b7ef5e125fa67;hp=e5f188e9d44c2ff732706e0bf6c417e5c1b4f9af;hpb=a1a6c76a214ad1935032826713cabaf9ac57bf07;p=senf.git diff --git a/Scheduler/ClockService.cc b/Scheduler/ClockService.cc index e5f188e..7754f4c 100644 --- a/Scheduler/ClockService.cc +++ b/Scheduler/ClockService.cc @@ -27,137 +27,62 @@ //#include "ClockService.ih" // Custom includes -#include -#include -#include -#include -#include "../Utils/Exception.hh" +#include +#include "../Utils/Console/Console.hh" //#include "ClockService.mpp" #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -#define CheckError(op,args) if (op args < 0) throwErrno(# op, errno) - -/////////////////////////////////////////////////////////////////////////// -// senf::ClockService::Impl - -struct senf::ClockService::Impl -{ - Impl(); - - void block(); - void unblock(); - - /// Internal: temporarily block signals (RAII idiom) - struct Blocker { - Blocker(Impl * i) : impl(i) { impl->block(); } - ~Blocker() { impl->unblock(); } - Impl * impl; - }; - - static void timer(int); - - struct sigaction oldaction; - struct itimerval olditimer; - sigset_t alrm_set; -}; - -prefix_ senf::ClockService::Impl::Impl() -{ - CheckError( sigemptyset, (&alrm_set) ); - CheckError( sigaddset, (&alrm_set, SIGALRM) ); -} - -prefix_ void senf::ClockService::Impl::block() -{ - CheckError( sigprocmask, (SIG_BLOCK, &alrm_set, 0) ); -} - -prefix_ void senf::ClockService::Impl::unblock() -{ - CheckError( sigprocmask, (SIG_UNBLOCK, &alrm_set, 0) ); -} - -prefix_ void senf::ClockService::Impl::timer(int) -{ - ClockService::instance().timer(); -} - -/////////////////////////////////////////////////////////////////////////// -// senf::ClockService - -prefix_ senf::ClockService::~ClockService() +prefix_ void +senf::parseClockServiceInterval(console::ParseCommandInfo::TokensRange const & tokens, + ClockService::clock_type & out) { - setitimer(ITIMER_REAL, &impl_->olditimer, 0); - sigaction(SIGALRM, &impl_->oldaction, 0); -} - -//////////////////////////////////////// -// private members - -prefix_ senf::ClockService::ClockService() - : impl_(new ClockService::Impl()) -{ - restart_m(false); -} - -prefix_ void senf::ClockService::timer() -{ - boost::posix_time::ptime time (boost::posix_time::microsec_clock::universal_time()); - if (checkSkew(time)) - clockSkew(time, heartbeat_ + boost::posix_time::seconds( - ClockService::CheckInterval)); - heartbeat_ = time; -} - -prefix_ void senf::ClockService::restart_m(bool restart) -{ - if (restart) - // if any syscall fails, the alarm signal stays blocked which is correct - impl_->block(); - - base_ = boost::posix_time::microsec_clock::universal_time(); - heartbeat_ = base_; - - struct sigaction action; - action.sa_handler = & senf::ClockService::Impl::timer; - CheckError( sigemptyset, (&action.sa_mask) ); - action.sa_flags = SA_RESTART; - CheckError( sigaction, (SIGALRM, &action, restart ? 0 : &impl_->oldaction) ); - - restartTimer(restart); - - impl_->unblock(); -} - -prefix_ void senf::ClockService::restartTimer(bool restart) -{ - struct itimerval itimer; - itimer.it_interval.tv_sec = CheckInterval; - itimer.it_interval.tv_usec = 0; - itimer.it_value.tv_sec = CheckInterval; - itimer.it_value.tv_usec = 0; - CheckError( setitimer, (ITIMER_REAL, &itimer, restart ? 0 : &impl_->olditimer) ); + out = 0; + std::string value; + { + senf::console::CheckedArgumentIteratorWrapper arg (tokens); + senf::console::parse( *(arg++), value ); + } + static boost::sregex_iterator::regex_type rx ("[mun]?[dhms]"); + boost::sregex_iterator i (value.begin(), value.end(), rx); + boost::sregex_iterator const i_end; + std::string::const_iterator j (value.begin()); + for (; i != i_end; ++i) { + boost::sregex_iterator::value_type::value_type match ((*i)[0]); + long double v (boost::lexical_cast(std::string(j, match.first))); + char scale (0); + char unit (0); + if (match.length() == 2) { + scale = *match.first; + unit = *boost::next(match.first); + } else { + SENF_ASSERT( match.length() == 1); + unit = *match.first; + } + switch (scale) { + case 0: break; + case 'n': v /= 1000.0; + case 'u': v /= 1000.0; + case 'm': v /= 1000.0; + } + switch (unit) { + case 'd': v *= 24.0; + case 'h': v *= 60.0; + case 'm': v *= 60.0; + case 's': v *= 1000000000.0; + } + out += senf::ClockService::nanoseconds(senf::ClockService::int64_type(v)); + j = match.second; + } + if (j != value.end()) + throw senf::console::SyntaxErrorException(); } -prefix_ void senf::ClockService::updateSkew(boost::posix_time::ptime time) +prefix_ void senf::formatClockServiceInterval(ClockService::clock_type interval, + std::ostream & os) { - Impl::Blocker alrmBlocker (impl_.get()); - - // Make a second 'checkSkew' test, this time with SIGALRM blocked. See - // senf::ClockService::now_i() - - if (checkSkew(time)) { - struct itimerval itimer; - CheckError( getitimer, (ITIMER_REAL, &itimer) ); - clockSkew(time, (heartbeat_ - + boost::posix_time::seconds(CheckInterval) - - boost::posix_time::seconds(itimer.it_value.tv_sec) - - boost::posix_time::microseconds(itimer.it_value.tv_usec))); - heartbeat_ = time; - restartTimer(); - } + os << interval << "ns"; } ///////////////////////////////cc.e////////////////////////////////////////