From 4254cb04e1cbc9ee349f79e9b7b68581b6a6a415 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Thu, 18 Jul 2013 10:43:28 +0200 Subject: [PATCH] Reduce IPC with timer service in timed semaphore Instead of using msleep to sleep periodically, and then increase jiffies counter in the alarm scheduler implementation of the timed semaphore use the 'trigger_periodic' call introduced by the change of the timer session interface into an asynchronous one. Thereby, we can reduce the necessary IPC communication with the timer service effectively. Ref #35 --- os/include/os/timed_semaphore.h | 40 +++++++++---------- os/include/timer_session/timer_session.h | 2 +- os/src/lib/timed_semaphore/timed_semaphore.cc | 8 ++-- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/os/include/os/timed_semaphore.h b/os/include/os/timed_semaphore.h index 4afd58f15..45f886d8e 100644 --- a/os/include/os/timed_semaphore.h +++ b/os/include/os/timed_semaphore.h @@ -34,22 +34,25 @@ namespace Genode { { private: - Timer::Connection _timer; /* timer session */ - Genode::Alarm::Time _jiffies; /* jiffies counter */ + enum { JIFFIES_STEP_MS = 10 }; + + Timer::Connection _timer; /* timer session */ + Signal_context _context; + Signal_receiver _receiver; + Genode::Alarm::Time _time; /* current time */ void entry(void); public: - enum { GRANULARITY_MSECS = 10 }; - - Timeout_thread() - : Thread<4096>("alarm-timer"), _jiffies(0) + Timeout_thread() : Thread<4096>("alarm-timer"), _time(0) { + _timer.sigh(_receiver.manage(&_context)); + _timer.trigger_periodic(JIFFIES_STEP_MS*1000); start(); } - Genode::Alarm::Time time(void) { return _jiffies; } + Genode::Alarm::Time time(void) { return _time; } /* * Returns the singleton timeout-thread used for all timeouts. @@ -134,18 +137,21 @@ namespace Genode { Timed_semaphore *_sem; /* Semaphore we block on */ Element *_element; /* Queue element timeout belongs to */ bool _triggered; /* Timeout expired */ + Time _start; public: Timeout(Time duration, Timed_semaphore *s, Element *e) : _sem(s), _element(e), _triggered(false) { - Time t = duration + Timeout_thread::alarm_timer()->time(); - Timeout_thread::alarm_timer()->schedule_absolute(this, t); + Timeout_thread *tt = Timeout_thread::alarm_timer(); + _start = tt->time(); + tt->schedule_absolute(this, _start + duration); } - void discard(void) { Timeout_thread::alarm_timer()->discard(this); } + void discard(void) { Timeout_thread::alarm_timer()->discard(this); } bool triggered(void) { return _triggered; } + Time start() { return _start; } protected: @@ -177,8 +183,6 @@ namespace Genode { */ Alarm::Time down(Alarm::Time t) { - /* Track start time */ - Alarm::Time starttime = Timeout_thread::alarm_timer()->time(); Semaphore::_meta_lock.lock(); if (--Semaphore::_cnt < 0) { @@ -190,11 +194,6 @@ namespace Genode { throw Genode::Nonblocking_exception(); } - /* Warn if someone choose a undersized timeout */ - if (t < Timeout_thread::GRANULARITY_MSECS && t > 0) - PWRN("We only support granularity of %d msecs, you choose %ld", - Timeout_thread::GRANULARITY_MSECS, t); - /* * Create semaphore queue element representing the thread * in the wait queue. @@ -222,12 +221,13 @@ namespace Genode { */ if (to.triggered()) throw Genode::Timeout_exception(); + + /* return blocking time */ + return Timeout_thread::alarm_timer()->time() - to.start(); } else { Semaphore::_meta_lock.unlock(); } - - /* return blocking time */ - return Timeout_thread::alarm_timer()->time() - starttime; + return 0; } diff --git a/os/include/timer_session/timer_session.h b/os/include/timer_session/timer_session.h index 4fa766ba4..1a396d057 100644 --- a/os/include/timer_session/timer_session.h +++ b/os/include/timer_session/timer_session.h @@ -30,7 +30,7 @@ namespace Timer { virtual ~Session() { } /** - * Program single timeout (in microseconds) + * Program single timeout (relative from now in microseconds) */ virtual void trigger_once(unsigned us) = 0; diff --git a/os/src/lib/timed_semaphore/timed_semaphore.cc b/os/src/lib/timed_semaphore/timed_semaphore.cc index 1be7fa3c4..44e343317 100644 --- a/os/src/lib/timed_semaphore/timed_semaphore.cc +++ b/os/src/lib/timed_semaphore/timed_semaphore.cc @@ -17,11 +17,13 @@ void Genode::Timeout_thread::entry() { while (true) { - _timer.msleep(GRANULARITY_MSECS); - _jiffies += GRANULARITY_MSECS; + Signal s = _receiver.wait_for_signal(); + + /* increase jiffies counter related to received signals */ + _time += JIFFIES_STEP_MS * s.num(); /* handle timouts of this point in time */ - Genode::Alarm_scheduler::handle(_jiffies); + Genode::Alarm_scheduler::handle(_time); } }