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
This commit is contained in:
Stefan Kalkowski 2013-07-18 10:43:28 +02:00 committed by Norman Feske
parent 7dfab657b2
commit 4254cb04e1
3 changed files with 26 additions and 24 deletions

View File

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

View File

@ -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;

View File

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