timer test: trigger timeout-masking bug

Issue #1646
This commit is contained in:
Norman Feske 2015-08-12 09:58:58 +02:00 committed by Christian Helmuth
parent 4992903233
commit e410ecc995
1 changed files with 43 additions and 4 deletions

View File

@ -75,6 +75,37 @@ class Timer_client : public Genode::List<Timer_client>::Element,
};
/**
* Timer client that continuously reprograms timeouts
*/
struct Timer_stressful_client : Timer::Connection, Genode::Thread<STACK_SIZE>
{
unsigned long us;
/*
* In principle, we could constantly execute 'trigger_once' in a busy loop.
* This however would significantly skew the precision of the timer on
* platforms w/o priority support. The behaviour would highly depend on the
* kernel's scheduling and its parameters such as the time-slice length. To
* even out those kernel-specific peculiarities, we let the stressful
* client delay its execution after each iteration instead of keeping it
* busy all the time. The delay must be smaller than scheduled 'us' to
* trigger the edge case of constantly reprogramming timeouts that never
* trigger.
*/
Timer::Connection delayer;
void entry() { for (;;) { trigger_once(us); delayer.usleep(us/2); } }
Timer_stressful_client(unsigned long us)
:
Thread("timer_stressful_client"), us(us)
{
Genode::Thread<STACK_SIZE>::start();
}
};
using namespace Genode;
extern "C" int usleep(unsigned long usec);
@ -87,10 +118,18 @@ int main(int argc, char **argv)
static Genode::List<Timer_client> timer_clients;
static Timer::Connection main_timer;
/* check long single timeout */
printf("register two-seconds timeout...\n");
main_timer.msleep(2000);
printf("timeout fired\n");
/*
* Check long single timeout in the presence of another client that
* reprograms timeouts all the time.
*/
{
/* will get destructed at the end of the current scope */
Timer_stressful_client stressful_client(250*1000);
printf("register two-seconds timeout...\n");
main_timer.msleep(2000);
printf("timeout fired\n");
}
/* check periodic timeouts */
Signal_receiver sig_rcv;