mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-25 08:21:08 +00:00
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:
parent
7dfab657b2
commit
4254cb04e1
@ -34,22 +34,25 @@ namespace Genode {
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
enum { JIFFIES_STEP_MS = 10 };
|
||||||
|
|
||||||
Timer::Connection _timer; /* timer session */
|
Timer::Connection _timer; /* timer session */
|
||||||
Genode::Alarm::Time _jiffies; /* jiffies counter */
|
Signal_context _context;
|
||||||
|
Signal_receiver _receiver;
|
||||||
|
Genode::Alarm::Time _time; /* current time */
|
||||||
|
|
||||||
void entry(void);
|
void entry(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum { GRANULARITY_MSECS = 10 };
|
Timeout_thread() : Thread<4096>("alarm-timer"), _time(0)
|
||||||
|
|
||||||
Timeout_thread()
|
|
||||||
: Thread<4096>("alarm-timer"), _jiffies(0)
|
|
||||||
{
|
{
|
||||||
|
_timer.sigh(_receiver.manage(&_context));
|
||||||
|
_timer.trigger_periodic(JIFFIES_STEP_MS*1000);
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::Alarm::Time time(void) { return _jiffies; }
|
Genode::Alarm::Time time(void) { return _time; }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the singleton timeout-thread used for all timeouts.
|
* Returns the singleton timeout-thread used for all timeouts.
|
||||||
@ -134,18 +137,21 @@ namespace Genode {
|
|||||||
Timed_semaphore *_sem; /* Semaphore we block on */
|
Timed_semaphore *_sem; /* Semaphore we block on */
|
||||||
Element *_element; /* Queue element timeout belongs to */
|
Element *_element; /* Queue element timeout belongs to */
|
||||||
bool _triggered; /* Timeout expired */
|
bool _triggered; /* Timeout expired */
|
||||||
|
Time _start;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Timeout(Time duration, Timed_semaphore *s, Element *e)
|
Timeout(Time duration, Timed_semaphore *s, Element *e)
|
||||||
: _sem(s), _element(e), _triggered(false)
|
: _sem(s), _element(e), _triggered(false)
|
||||||
{
|
{
|
||||||
Time t = duration + Timeout_thread::alarm_timer()->time();
|
Timeout_thread *tt = Timeout_thread::alarm_timer();
|
||||||
Timeout_thread::alarm_timer()->schedule_absolute(this, t);
|
_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; }
|
bool triggered(void) { return _triggered; }
|
||||||
|
Time start() { return _start; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -177,8 +183,6 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
Alarm::Time down(Alarm::Time t)
|
Alarm::Time down(Alarm::Time t)
|
||||||
{
|
{
|
||||||
/* Track start time */
|
|
||||||
Alarm::Time starttime = Timeout_thread::alarm_timer()->time();
|
|
||||||
Semaphore::_meta_lock.lock();
|
Semaphore::_meta_lock.lock();
|
||||||
|
|
||||||
if (--Semaphore::_cnt < 0) {
|
if (--Semaphore::_cnt < 0) {
|
||||||
@ -190,11 +194,6 @@ namespace Genode {
|
|||||||
throw Genode::Nonblocking_exception();
|
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
|
* Create semaphore queue element representing the thread
|
||||||
* in the wait queue.
|
* in the wait queue.
|
||||||
@ -222,12 +221,13 @@ namespace Genode {
|
|||||||
*/
|
*/
|
||||||
if (to.triggered())
|
if (to.triggered())
|
||||||
throw Genode::Timeout_exception();
|
throw Genode::Timeout_exception();
|
||||||
|
|
||||||
|
/* return blocking time */
|
||||||
|
return Timeout_thread::alarm_timer()->time() - to.start();
|
||||||
} else {
|
} else {
|
||||||
Semaphore::_meta_lock.unlock();
|
Semaphore::_meta_lock.unlock();
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
/* return blocking time */
|
|
||||||
return Timeout_thread::alarm_timer()->time() - starttime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ namespace Timer {
|
|||||||
virtual ~Session() { }
|
virtual ~Session() { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Program single timeout (in microseconds)
|
* Program single timeout (relative from now in microseconds)
|
||||||
*/
|
*/
|
||||||
virtual void trigger_once(unsigned us) = 0;
|
virtual void trigger_once(unsigned us) = 0;
|
||||||
|
|
||||||
|
@ -17,11 +17,13 @@
|
|||||||
void Genode::Timeout_thread::entry()
|
void Genode::Timeout_thread::entry()
|
||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
_timer.msleep(GRANULARITY_MSECS);
|
Signal s = _receiver.wait_for_signal();
|
||||||
_jiffies += GRANULARITY_MSECS;
|
|
||||||
|
/* increase jiffies counter related to received signals */
|
||||||
|
_time += JIFFIES_STEP_MS * s.num();
|
||||||
|
|
||||||
/* handle timouts of this point in time */
|
/* handle timouts of this point in time */
|
||||||
Genode::Alarm_scheduler::handle(_jiffies);
|
Genode::Alarm_scheduler::handle(_time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user