From: g0dil Date: Thu, 19 Feb 2009 12:44:01 +0000 (+0000) Subject: Scheduler: Add timerfd() kernel availability check X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=bec6af3105a72bd23d560e1934ec3a64bd9979d5;p=senf.git Scheduler: Add timerfd() kernel availability check git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1129 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Scheduler/Scheduler.cc b/Scheduler/Scheduler.cc index f40bf69..9457743 100644 --- a/Scheduler/Scheduler.cc +++ b/Scheduler/Scheduler.cc @@ -123,6 +123,18 @@ prefix_ bool senf::scheduler::empty() && detail::EventHookDispatcher::instance().empty(); } +prefix_ void senf::scheduler::hiresTimers() +{ +#ifdef HAVE_TIMERFD + if (haveScalableHiresTimers()) + detail::TimerDispatcher::instance().timerSource( + std::auto_ptr(new detail::TimerFDTimerSource())); + else +#endif + detail::TimerDispatcher::instance().timerSource( + std::auto_ptr(new detail::POSIXTimerSource())); +} + /////////////////////////////////////////////////////////////////////////// // senf::schedulerLogTimeSource diff --git a/Scheduler/Scheduler.cci b/Scheduler/Scheduler.cci index acce9db..75dcb06 100644 --- a/Scheduler/Scheduler.cci +++ b/Scheduler/Scheduler.cci @@ -54,18 +54,6 @@ prefix_ unsigned senf::scheduler::hangCount() return scheduler::detail::FIFORunner::instance().hangCount(); } -prefix_ void senf::scheduler::hiresTimers() -{ -#ifdef HAVE_TIMERFD - if (haveScalableHiresTimers()) - detail::TimerDispatcher::instance().timerSource( - std::auto_ptr(new detail::TimerFDTimerSource())); - else -#endif - detail::TimerDispatcher::instance().timerSource( - std::auto_ptr(new detail::POSIXTimerSource())); -} - prefix_ void senf::scheduler::loresTimers() { detail::TimerDispatcher::instance().timerSource( @@ -77,7 +65,7 @@ prefix_ bool senf::scheduler::haveScalableHiresTimers() #ifndef HAVE_TIMERFD return false; #else - return true; + return detail::TimerFDTimerSource::haveTimerFD(); #endif } diff --git a/Scheduler/Scheduler.test.cc b/Scheduler/Scheduler.test.cc index 75bc76a..08e9dc8 100644 --- a/Scheduler/Scheduler.test.cc +++ b/Scheduler/Scheduler.test.cc @@ -337,19 +337,19 @@ BOOST_AUTO_UNIT_TEST(testSchedulerHiresTimers) BOOST_MESSAGE( "Using timerfd() hires timers" ); else BOOST_MESSAGE( "Using POSIX hires timers"); - senf::scheduler::hiresTimers(); + SENF_CHECK_NO_THROW( senf::scheduler::hiresTimers() ); BOOST_CHECK( senf::scheduler::usingHiresTimers() ); schedulerTest(); - senf::scheduler::loresTimers(); + SENF_CHECK_NO_THROW( senf::scheduler::loresTimers() ); BOOST_CHECK( ! senf::scheduler::usingHiresTimers() ); } BOOST_AUTO_UNIT_TEST(testSchedulerPOSIXTimers) { if (senf::scheduler::haveScalableHiresTimers()) { - senf::scheduler::detail::TimerDispatcher::instance().timerSource( - std::auto_ptr( - new senf::scheduler::detail::POSIXTimerSource())); + SENF_CHECK_NO_THROW( senf::scheduler::detail::TimerDispatcher::instance().timerSource( + std::auto_ptr( + new senf::scheduler::detail::POSIXTimerSource())) ); schedulerTest(); senf::scheduler::loresTimers(); } diff --git a/Scheduler/TimerSource.cc b/Scheduler/TimerSource.cc index ac1baa3..fe6b7d1 100644 --- a/Scheduler/TimerSource.cc +++ b/Scheduler/TimerSource.cc @@ -217,6 +217,35 @@ prefix_ void senf::scheduler::detail::TimerFDTimerSource::enable() prefix_ void senf::scheduler::detail::TimerFDTimerSource::disable() {} +namespace { + + struct TimerFdCheck + { + TimerFdCheck(); + bool timerFdOk; + }; + + TimerFdCheck::TimerFdCheck() + : timerFdOk (false) + { + int fd (timerfd_create(CLOCK_MONOTONIC, 0)); + if (fd == -1) { + if (errno != EINVAL) + SENF_THROW_SYSTEM_EXCEPTION("timerfd_create()"); + } + else { + timerFdOk = true; + close(fd); + } + } + +} +prefix_ bool senf::scheduler::detail::TimerFDTimerSource::haveTimerFD() +{ + static TimerFdCheck check; + return check.timerFdOk; +} + prefix_ void senf::scheduler::detail::TimerFDTimerSource::signal(int events) { uint64_t expirations (0); diff --git a/Scheduler/TimerSource.hh b/Scheduler/TimerSource.hh index d3afcad..c520348 100644 --- a/Scheduler/TimerSource.hh +++ b/Scheduler/TimerSource.hh @@ -106,6 +106,8 @@ namespace detail { virtual void enable(); virtual void disable(); + static bool haveTimerFD(); + private: virtual void signal(int events); void reschedule();