2011-12-22 16:19:25 +01:00
|
|
|
/*
|
|
|
|
* \brief Test for timer service
|
|
|
|
* \author Norman Feske
|
2017-01-11 17:35:31 +01:00
|
|
|
* \author Martin Stein
|
2011-12-22 16:19:25 +01:00
|
|
|
* \date 2009-06-22
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-01-11 17:35:31 +01:00
|
|
|
* Copyright (C) 2009-2017 Genode Labs GmbH
|
2011-12-22 16:19:25 +01:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU General Public License version 2.
|
|
|
|
*/
|
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
/* Genode includes */
|
|
|
|
#include <base/component.h>
|
|
|
|
#include <base/heap.h>
|
2011-12-22 16:19:25 +01:00
|
|
|
#include <timer_session/connection.h>
|
2017-01-11 17:35:31 +01:00
|
|
|
#include <base/registry.h>
|
|
|
|
|
|
|
|
using namespace Genode;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
struct Lazy_test
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2017-01-11 17:35:31 +01:00
|
|
|
struct Faster_timer_too_slow : Exception { };
|
|
|
|
|
|
|
|
Env &env;
|
|
|
|
Signal_transmitter done;
|
|
|
|
Timer::Connection slow_timer { env };
|
|
|
|
Signal_handler<Lazy_test> slow_handler { env.ep(), *this,
|
|
|
|
&Lazy_test::handle_slow_timer };
|
|
|
|
Timer::Connection fast_timer { env };
|
|
|
|
Signal_handler<Lazy_test> fast_handler { env.ep(), *this,
|
|
|
|
&Lazy_test::handle_fast_timer };
|
|
|
|
Timer::Connection faster_timer { env };
|
|
|
|
Signal_handler<Lazy_test> faster_handler { env.ep(), *this,
|
|
|
|
&Lazy_test::handle_faster_timer };
|
|
|
|
|
|
|
|
void handle_slow_timer()
|
|
|
|
{
|
|
|
|
log("timeout fired");
|
|
|
|
done.submit();
|
|
|
|
}
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
void handle_fast_timer() { throw Faster_timer_too_slow(); }
|
|
|
|
void handle_faster_timer() { set_fast_timers(); }
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
void set_fast_timers()
|
|
|
|
{
|
|
|
|
enum { TIMEOUT_US = 50*1000 };
|
|
|
|
fast_timer.trigger_once(TIMEOUT_US);
|
|
|
|
faster_timer.trigger_once(TIMEOUT_US/2);
|
|
|
|
}
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
Lazy_test(Env &env, Signal_context_capability done) : env(env), done(done)
|
|
|
|
{
|
|
|
|
slow_timer.sigh(slow_handler);
|
|
|
|
fast_timer.sigh(fast_handler);
|
|
|
|
faster_timer.sigh(faster_handler);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
log("register two-seconds timeout...");
|
|
|
|
slow_timer.trigger_once(2*1000*1000);
|
|
|
|
set_fast_timers();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct Stress_test
|
|
|
|
{
|
|
|
|
struct Slave
|
|
|
|
{
|
|
|
|
Signal_handler<Slave> timer_handler;
|
|
|
|
Timer::Connection timer;
|
|
|
|
unsigned us;
|
|
|
|
unsigned count { 0 };
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
Slave(Env &env, unsigned ms)
|
|
|
|
: timer_handler(env.ep(), *this, &Slave::handle_timer),
|
|
|
|
timer(env), us(ms * 1000) { timer.sigh(timer_handler); }
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
void handle_timer()
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2017-01-11 17:35:31 +01:00
|
|
|
count++;
|
|
|
|
timer.trigger_once(us);
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
void dump() {
|
|
|
|
log("timer (period ", us / 1000, " ms) triggered ", count,
|
|
|
|
" times -> slept ", (us / 1000) * count, " ms"); }
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
void start() { timer.trigger_once(us); }
|
|
|
|
void stop() { timer.sigh(Signal_context_capability()); }
|
|
|
|
};
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
Env &env;
|
|
|
|
Signal_transmitter done;
|
|
|
|
Heap heap { &env.ram(), &env.rm() };
|
|
|
|
Timer::Connection timer { env };
|
|
|
|
unsigned count { 0 };
|
|
|
|
Signal_handler<Stress_test> handler { env.ep(), *this, &Stress_test::handle };
|
|
|
|
Registry<Registered<Slave> > slaves;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
void handle()
|
2015-08-12 09:58:58 +02:00
|
|
|
{
|
2017-01-11 17:35:31 +01:00
|
|
|
enum { MAX_COUNT = 10 };
|
|
|
|
if (count < MAX_COUNT) {
|
|
|
|
count++;
|
|
|
|
log("wait ", count, "/", (unsigned)MAX_COUNT);
|
|
|
|
timer.trigger_once(1000 * 1000);
|
|
|
|
} else {
|
|
|
|
slaves.for_each([&] (Slave &timer) { timer.stop(); });
|
|
|
|
slaves.for_each([&] (Slave &timer) { timer.dump(); });
|
|
|
|
done.submit();
|
|
|
|
}
|
2015-08-12 09:58:58 +02:00
|
|
|
}
|
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
Stress_test(Env &env, Signal_context_capability done) : env(env), done(done)
|
|
|
|
{
|
|
|
|
timer.sigh(handler);
|
|
|
|
for (unsigned ms = 1; ms < 28; ms++) {
|
|
|
|
new (heap) Registered<Slave>(slaves, env, ms); }
|
|
|
|
slaves.for_each([&] (Slave &slv) { slv.start(); });
|
|
|
|
timer.trigger_once(1000 * 1000);
|
|
|
|
}
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
~Stress_test() {
|
|
|
|
slaves.for_each([&] (Registered<Slave> &slv) { destroy(heap, &slv); }); }
|
|
|
|
};
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
struct Main
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
2017-01-11 17:35:31 +01:00
|
|
|
Env &env;
|
|
|
|
Constructible<Lazy_test> test_1;
|
|
|
|
Signal_handler<Main> test_1_done { env.ep(), *this, &Main::handle_test_1_done };
|
|
|
|
Constructible<Stress_test> test_2;
|
|
|
|
Signal_handler<Main> test_2_done { env.ep(), *this, &Main::handle_test_2_done };
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
void handle_test_1_done()
|
2015-08-12 09:58:58 +02:00
|
|
|
{
|
2017-01-11 17:35:31 +01:00
|
|
|
test_1.destruct();
|
|
|
|
test_2.construct(env, test_2_done);
|
2013-03-21 16:54:35 +01:00
|
|
|
}
|
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
void handle_test_2_done()
|
|
|
|
{
|
|
|
|
log("--- timer test finished ---");
|
|
|
|
env.parent().exit(0);
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
Main(Env &env) : env(env)
|
|
|
|
{
|
|
|
|
log("--- timer test ---");
|
|
|
|
test_1.construct(env, test_1_done);
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
2017-01-11 17:35:31 +01:00
|
|
|
};
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
|
2017-01-11 17:35:31 +01:00
|
|
|
void Component::construct(Env &env) { static Main main(env); }
|