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); } }