X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Scheduler%2FClockService.cc;h=7754f4c2380efe67f3b4532bc2720025e23b9162;hb=a1fdb7bb122f0b05be809a922d4b7ef5e125fa67;hp=010bd2093a0aa32936ec1b1540dbcdc5061698e0;hpb=3d16600678b948ff3bd0e4fd2a1a800fcc629a03;p=senf.git diff --git a/Scheduler/ClockService.cc b/Scheduler/ClockService.cc index 010bd20..7754f4c 100644 --- a/Scheduler/ClockService.cc +++ b/Scheduler/ClockService.cc @@ -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,125 +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 CheckErrno(op,args) if (op args < 0) throw SystemException(# op, errno) - -struct senf::ClockService::Impl -{ - Impl(); - - void block(); - void unblock(); - - 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() -{ - CheckErrno( sigemptyset, (&alrm_set) ); - CheckErrno( sigaddset, (&alrm_set, SIGALRM) ); -} - -prefix_ void senf::ClockService::Impl::block() -{ - CheckErrno( sigprocmask, (SIG_BLOCK, &alrm_set, 0) ); -} - -prefix_ void senf::ClockService::Impl::unblock() -{ - CheckErrno( sigprocmask, (SIG_UNBLOCK, &alrm_set, 0) ); -} - -prefix_ void senf::ClockService::Impl::timer(int) -{ - boost::posix_time::ptime time (boost::posix_time::microsec_clock::universal_time()); - if (ClockService::instance().checkSkew(time)) - ClockService::instance().clockSkew( - time, ClockService::instance().heartbeat_ + boost::posix_time::seconds( - ClockService::CheckInterval)); - ClockService::instance().heartbeat_ = time; -} - -/////////////////////////////////////////////////////////////////////////// -// 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() - : base_ (boost::posix_time::microsec_clock::universal_time()), - heartbeat_ (base_), impl_(new ClockService::Impl()) -{ - struct sigaction action; - action.sa_handler = & senf::ClockService::Impl::timer; - CheckErrno( sigemptyset, (&action.sa_mask) ); - action.sa_flags = SA_RESTART; - CheckErrno( sigaction, (SIGALRM, &action, &impl_->oldaction) ); - - 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; - CheckErrno( setitimer, (ITIMER_REAL, &itimer, &impl_->olditimer) ); - impl_->unblock(); -} - -prefix_ void senf::ClockService::restart_i() -{ - impl_->block(); // if any syscall fails, the alarm signal stays blocked which is correct - base_ = boost::posix_time::microsec_clock::universal_time(); - heartbeat_ = base_; - - struct sigaction action; - action.sa_handler = & senf::ClockService::Impl::timer; - CheckErrno( sigemptyset, (&action.sa_mask) ); - action.sa_flags = SA_RESTART; - CheckErrno( sigaction, (SIGALRM, &action, 0) ); - - 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; - CheckErrno( setitimer, (ITIMER_REAL, &itimer, 0) ); - impl_->unblock(); + 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()); - struct itimerval itimer; - CheckErrno( 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))); + os << interval << "ns"; } ///////////////////////////////cc.e////////////////////////////////////////