X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Scheduler%2FClockService.cci;h=32c774821284f8acb8cf2f48853a18d6a9897bbd;hb=10985d71f77b627bc4da543d7114feb7c4529329;hp=117e4754e2982492b7cac247dcefc7f7478b7429;hpb=e8b91aa6a817af6d9a3714e7b66be6c0d6b0a4e5;p=senf.git diff --git a/Scheduler/ClockService.cci b/Scheduler/ClockService.cci index 117e475..32c7748 100644 --- a/Scheduler/ClockService.cci +++ b/Scheduler/ClockService.cci @@ -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 @@ -24,7 +24,7 @@ \brief ClockService inline non-template implementation */ // Custom includes -#include "boost/date_time/posix_time/posix_time_types.hpp" +#include #define prefix_ inline ///////////////////////////////cci.p/////////////////////////////////////// @@ -32,6 +32,63 @@ /////////////////////////////////////////////////////////////////////////// // senf::ClockService +//////////////////////////////////////// +// private members + +prefix_ bool senf::ClockService::checkSkew(boost::posix_time::ptime time) +{ + boost::posix_time::ptime h (heartbeat_); // reduce chance for race condition + return time < h || (time - h) > boost::posix_time::seconds(2*CheckInterval); +} + +prefix_ void senf::ClockService::clockSkew(boost::posix_time::ptime time, + boost::posix_time::ptime expected) +{ + base_ += (time - expected); +} + +prefix_ senf::ClockService::clock_type senf::ClockService::clock_m(abstime_type time) +{ + ///\fixme What happens, if base_ is changed in SIGALRM while reading it here ? + + // Idea: Have *two* base values: one is written by the SIGALRM handler, the other is only + // Written by synchronous code. If they differ, we block signals, copy over and continue. If + // they transiently differ because we are reading the SIGALRM value while it is being changed + // this does not matter: We will then still copy it over. + + boost::posix_time::time_duration delta (time - base_); + return clock_type( delta.ticks() ) + * clock_type( 1000000000UL / boost::posix_time::time_duration::ticks_per_second() ); +} + +prefix_ senf::ClockService::clock_type senf::ClockService::now_m() +{ + // We want to make the normal case (no skew) really fast. This first 'checkSkew' *might* + // transiently fail if a SIGALRM is delivered in the midst of the test. updateSkew will + // therefore block signals and do the check again to make sure. + // + // The opposite case (the test returns 'false' even though it should return 'true') is so highly + // improbable that it is treated as academic. (it will be catched by the next SIGALRM) + + boost::posix_time::ptime time (boost::posix_time::microsec_clock::universal_time()); + if (checkSkew(time)) + updateSkew(time); + + // 'clock' will pick up the corrected base_ value if needed. + return clock_m(time); +} + +prefix_ senf::ClockService::abstime_type senf::ClockService::abstime_m(clock_type clock) +{ +#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG + return base_ + boost::posix_time::nanoseconds(clock); +#else + return base_ + boost::posix_time::microseconds((clock+500)/1000); +#endif +} + +// public members + prefix_ senf::ClockService::clock_type senf::ClockService::now() { return instance().now_m(); @@ -47,92 +104,89 @@ prefix_ senf::ClockService::clock_type senf::ClockService::clock(abstime_type ti return instance().clock_m(time); } -prefix_ senf::ClockService::clock_type senf::ClockService::nanoseconds(clock_type v) +prefix_ senf::ClockService::clock_type senf::ClockService::from_time_t(time_t const & time) +{ + return clock( boost::posix_time::from_time_t(time) ); +} + +prefix_ senf::ClockService::clock_type senf::ClockService::nanoseconds(int64_type v) { return v; } -prefix_ senf::ClockService::clock_type senf::ClockService::microseconds(clock_type v) +prefix_ senf::ClockService::clock_type senf::ClockService::microseconds(int64_type v) { return v * nanoseconds(1000); } -prefix_ senf::ClockService::clock_type senf::ClockService::milliseconds(clock_type v) +prefix_ senf::ClockService::clock_type senf::ClockService::milliseconds(int64_type v) { return v * microseconds(1000); } -prefix_ senf::ClockService::clock_type senf::ClockService::seconds(clock_type v) +prefix_ senf::ClockService::clock_type senf::ClockService::seconds(int64_type v) { return v * milliseconds(1000); } -prefix_ senf::ClockService::clock_type senf::ClockService::minutes(clock_type v) +prefix_ senf::ClockService::clock_type senf::ClockService::minutes(int64_type v) { return v * seconds(60); } -prefix_ senf::ClockService::clock_type senf::ClockService::hours(clock_type v) +prefix_ senf::ClockService::clock_type senf::ClockService::hours(int64_type v) { return v * minutes(60); } -prefix_ senf::ClockService::clock_type senf::ClockService::days(clock_type v) +prefix_ senf::ClockService::clock_type senf::ClockService::days(int64_type v) { return v * hours(24); } -prefix_ void senf::ClockService::restart() +prefix_ senf::ClockService::clock_type senf::ClockService::in_nanoseconds(int64_type v) { - instance().restart_m(); + return v; } -//////////////////////////////////////// -// private members +prefix_ senf::ClockService::clock_type senf::ClockService::in_microseconds(int64_type v) +{ + return v / nanoseconds(1000); +} -prefix_ senf::ClockService::clock_type senf::ClockService::now_m() +prefix_ senf::ClockService::clock_type senf::ClockService::in_milliseconds(int64_type v) { - // We want to make the normal case (no skew) really fast. This first 'checkSkew' *might* - // transiently fail if a SIGALRM is delivered in the midst of the test. updateSkew will - // therefore block signals and do the check again to make sure. - // - // The opposite case (the test returns 'false' even though it should return 'true') is so highly - // improbable that it is treated as academic. (it will be catched by the next SIGALRM) + return v / microseconds(1000); +} - boost::posix_time::ptime time (boost::posix_time::microsec_clock::universal_time()); - if (checkSkew(time)) - updateSkew(time); - - // 'clock' will pick up the corrected base_ value if needed. - return clock_m(time); +prefix_ senf::ClockService::clock_type senf::ClockService::in_seconds(int64_type v) +{ + return v / milliseconds(1000); } -prefix_ senf::ClockService::abstime_type senf::ClockService::abstime_m(clock_type clock) +prefix_ senf::ClockService::clock_type senf::ClockService::in_minutes(int64_type v) { -#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG - return base_ + boost::posix_time::nanoseconds(clock); -#else - return base_ + boost::posix_time::microseconds((clock+500)/1000); -#endif + return v / seconds(60); } -prefix_ senf::ClockService::clock_type senf::ClockService::clock_m(abstime_type time) +prefix_ senf::ClockService::clock_type senf::ClockService::in_hours(int64_type v) { - boost::posix_time::time_duration delta (time - base_); - return clock_type( delta.ticks() ) - * clock_type( 1000000000UL / boost::posix_time::time_duration::ticks_per_second() ); + return v / minutes(60); } -prefix_ bool senf::ClockService::checkSkew(boost::posix_time::ptime time) +prefix_ senf::ClockService::clock_type senf::ClockService::in_days(int64_type v) { - boost::posix_time::ptime h (heartbeat_); // reduce chance for race condition - return time < h || (time - h) > boost::posix_time::seconds(2*CheckInterval); + return v / hours(24); } -prefix_ void senf::ClockService::clockSkew(boost::posix_time::ptime time, - boost::posix_time::ptime expected) +prefix_ senf::ClockService::clock_type senf::ClockService::from_timeval(timeval const & time) { - base_ += (time - expected); + return from_time_t(time.tv_sec) + ClockService::microseconds(time.tv_usec); +} + +prefix_ void senf::ClockService::restart() +{ + instance().restart_m(); } ///////////////////////////////cci.e///////////////////////////////////////