mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 23:42:32 +00:00
parent
5da281c1d8
commit
dc814ff0f1
@ -36,6 +36,9 @@ namespace Timer {
|
||||
|
||||
/**
|
||||
* Program periodic timeout (in microseconds)
|
||||
*
|
||||
* The first period will be triggered after 'us' at the latest,
|
||||
* but it might be triggered earlier as well.
|
||||
*/
|
||||
virtual void trigger_periodic(unsigned us) = 0;
|
||||
|
||||
|
@ -110,6 +110,7 @@ namespace Timer {
|
||||
|
||||
void sigh(Signal_context_capability sigh) { _sigh = sigh; }
|
||||
void periodic(bool periodic) { _periodic = periodic; }
|
||||
bool periodic() { return _periodic; }
|
||||
|
||||
|
||||
/*********************
|
||||
@ -182,10 +183,13 @@ namespace Timer {
|
||||
/**
|
||||
* Called from the '_trigger' function executed by the server activation
|
||||
*/
|
||||
void schedule_timeout(Genode::Alarm *alarm, Genode::Alarm::Time timeout)
|
||||
void schedule_timeout(Wake_up_alarm *alarm, Genode::Alarm::Time timeout)
|
||||
{
|
||||
Alarm::Time now = _platform_timer->curr_time();
|
||||
schedule_absolute(alarm, now + timeout);
|
||||
if (alarm->periodic()) {
|
||||
handle(now); /* update '_now' in 'Alarm_scheduler' */
|
||||
schedule(alarm, timeout);
|
||||
} else schedule_absolute(alarm, now + timeout);
|
||||
|
||||
/* interrupt current 'wait_for_timeout' */
|
||||
_platform_timer->schedule_timeout(0);
|
||||
@ -258,7 +262,7 @@ namespace Timer {
|
||||
unsigned long elapsed_ms() const
|
||||
{
|
||||
unsigned long const now = _timeout_scheduler.curr_time();
|
||||
return now - _initial_time;
|
||||
return (now - _initial_time) / 1000;
|
||||
}
|
||||
|
||||
void msleep(unsigned) { /* never called at the server side */ }
|
||||
|
@ -91,6 +91,34 @@ int main(int argc, char **argv)
|
||||
main_timer.msleep(2000);
|
||||
printf("timeout fired\n");
|
||||
|
||||
/* check periodic timeouts */
|
||||
Signal_receiver sig_rcv;
|
||||
Signal_context sig_cxt;
|
||||
Signal_context_capability sig = sig_rcv.manage(&sig_cxt);
|
||||
main_timer.sigh(sig);
|
||||
enum { PTEST_TIME_US = 2000000 };
|
||||
unsigned period_us = 500000, periods = PTEST_TIME_US / period_us, i = 0;
|
||||
printf("start periodic timeouts\n");
|
||||
for (unsigned j = 0; j < 5; j++) {
|
||||
unsigned elapsed_ms = main_timer.elapsed_ms();
|
||||
main_timer.trigger_periodic(period_us);
|
||||
while (i < periods) {
|
||||
Signal s = sig_rcv.wait_for_signal();
|
||||
i += s.num();
|
||||
}
|
||||
elapsed_ms = main_timer.elapsed_ms() - elapsed_ms;
|
||||
unsigned const min_ms = ((i - 1) * period_us) / 1000;
|
||||
unsigned const max_ms = (i * period_us) / 1000;
|
||||
if (min_ms > elapsed_ms || max_ms < elapsed_ms) {
|
||||
PERR("Timing %u ms period %u times failed: %u ms (min %u, max %u)",
|
||||
period_us / 1000, i, elapsed_ms, min_ms, max_ms);
|
||||
return -1;
|
||||
}
|
||||
printf("Done %u ms period %u times: %u ms (min %u, max %u)\n",
|
||||
period_us / 1000, i, elapsed_ms, min_ms, max_ms);
|
||||
i = 0, period_us /= 2, periods = PTEST_TIME_US / period_us;
|
||||
}
|
||||
|
||||
/* create timer clients with different periods */
|
||||
for (unsigned period_msec = 1; period_msec < 28; period_msec++) {
|
||||
Timer_client *tc = new (env()->heap()) Timer_client(period_msec);
|
||||
|
Loading…
Reference in New Issue
Block a user