From 43efb5b4e2b75858b1626b9564b900cc5e238c79 Mon Sep 17 00:00:00 2001 From: Alexander Weidinger Date: Thu, 7 Jan 2021 18:33:26 +0100 Subject: [PATCH] Add simple async signal example --- include/signals_session/client.h | 19 ++++++++ include/signals_session/connection.h | 14 ++++++ include/signals_session/signals_session.h | 21 +++++++++ run/signals.run | 46 +++++++++++++++++++ src/signals/client/main.cc | 19 ++++++++ src/signals/client/target.mk | 3 ++ src/signals/server/main.cc | 54 +++++++++++++++++++++++ src/signals/server/target.mk | 3 ++ 8 files changed, 179 insertions(+) create mode 100644 include/signals_session/client.h create mode 100644 include/signals_session/connection.h create mode 100644 include/signals_session/signals_session.h create mode 100644 run/signals.run create mode 100644 src/signals/client/main.cc create mode 100644 src/signals/client/target.mk create mode 100644 src/signals/server/main.cc create mode 100644 src/signals/server/target.mk diff --git a/include/signals_session/client.h b/include/signals_session/client.h new file mode 100644 index 0000000..a3b57f3 --- /dev/null +++ b/include/signals_session/client.h @@ -0,0 +1,19 @@ +#ifndef _INCLUDE__SIGNALS_SESSION__CLIENT_H_ +#define _INCLUDE__SIGNALS_SESSION__CLIENT_H_ + +#include +#include + +namespace Signals { struct Session_client; } + +struct Signals::Session_client : Genode::Rpc_client +{ + Session_client(Genode::Capability cap) : Genode::Rpc_client(cap) { + } + + Genode::Signal_context_capability get_sig_con() override { + return call(); + } +}; + +#endif /* _INCLUDE__SIGNALS_SESSION__CLIENT_H_ */ diff --git a/include/signals_session/connection.h b/include/signals_session/connection.h new file mode 100644 index 0000000..48ddcca --- /dev/null +++ b/include/signals_session/connection.h @@ -0,0 +1,14 @@ +#ifndef _INCLUDE__SIGNALS_SESSION__CONNECTION_H_ +#define _INCLUDE__SIGNALS_SESSION__CONNECTION_H_ + +#include +#include + +namespace Signals { struct Connection; } + +struct Signals::Connection : Genode::Connection, Session_client { + Connection(Genode::Env &env) : Genode::Connection(env, session(env.parent(), "ram_quota=6K, cap_quota=4")), + Session_client(cap()) { } +}; + +#endif /* _INCLUDE__SIGNALS_SESSION__CONNECTION_H_ */ diff --git a/include/signals_session/signals_session.h b/include/signals_session/signals_session.h new file mode 100644 index 0000000..14f0cfd --- /dev/null +++ b/include/signals_session/signals_session.h @@ -0,0 +1,21 @@ +#ifndef _INCLUDE__SIGNALS_SESSION__SIGNALS_SESSION_H +#define _INCLUDE__SIGNALS_SESSION__SIGNALS_SESSION_H + +#include +#include + +namespace Signals { struct Session; } + +struct Signals::Session : Genode::Session { + static const char *service_name() { return "Signals"; } + + enum { CAP_QUOTA = 2 }; + + virtual Genode::Signal_context_capability get_sig_con() = 0; + + GENODE_RPC(Rpc_get_sig_con, Genode::Signal_context_capability, get_sig_con); + + GENODE_RPC_INTERFACE(Rpc_get_sig_con); +}; + +#endif /* _INCLUDE__SIGNALS_SESSION__SIGNALS_SESSION_H */ diff --git a/run/signals.run b/run/signals.run new file mode 100644 index 0000000..cff9384 --- /dev/null +++ b/run/signals.run @@ -0,0 +1,46 @@ +# +# Build +# + +build { core init timer signals } + +create_boot_directory + +# +# Generate config +# + +install_config { + + + + + + + + + + + + + + + + + + + + + + +} + +# +# Boot image +# + +build_boot_image { core ld.lib.so init timer signals_client signals_server } + +append qemu_args " -nographic " + +run_genode_until forever diff --git a/src/signals/client/main.cc b/src/signals/client/main.cc new file mode 100644 index 0000000..ff4321b --- /dev/null +++ b/src/signals/client/main.cc @@ -0,0 +1,19 @@ +#include +#include +#include +#include + + +void Component::construct(Genode::Env &env) +{ + Signals::Connection _signals(env); + Genode::Signal_transmitter _signal_transmitter(_signals.get_sig_con()); + + Timer::Connection _timer(env); + + while(true) { + _timer.msleep(1000); + Genode::log("Sending signal…"); + _signal_transmitter.submit(); + }; +} diff --git a/src/signals/client/target.mk b/src/signals/client/target.mk new file mode 100644 index 0000000..947fca6 --- /dev/null +++ b/src/signals/client/target.mk @@ -0,0 +1,3 @@ +TARGET = signals_client +SRC_CC = main.cc +LIBS = base diff --git a/src/signals/server/main.cc b/src/signals/server/main.cc new file mode 100644 index 0000000..8362187 --- /dev/null +++ b/src/signals/server/main.cc @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include + +namespace Signals { + struct Session_component; + class Root_component; + struct Main; +} + +struct Signals::Session_component : Genode::Rpc_object { + Genode::Signal_context_capability _sig_con; + Genode::Signal_context_capability get_sig_con() override { + return _sig_con; + } + + Session_component(Genode::Signal_context_capability &sig_con) : _sig_con(sig_con) { } +}; + +class Signals::Root_component : public Genode::Root_component { +private: + Genode::Signal_context_capability _sig_con; +protected: + Session_component *_create_session(const char *) override { + return new (md_alloc()) Session_component(_sig_con); + } + +public: + Root_component(Genode::Entrypoint &ep, Genode::Allocator &alloc, Genode::Signal_context_capability sig_con) : Genode::Root_component(ep, alloc), _sig_con(sig_con) { } +}; + +struct Signals::Main { + Genode::Env &_env; + + Genode::Signal_handler
_sig_handler = { _env.ep(), *this, &Main::_handle_signal }; + + Genode::Sliced_heap sliced_heap { _env.ram(), _env.rm() }; + + Signals::Root_component root { _env.ep(), sliced_heap, _sig_handler }; + + Main(Genode::Env &env) : _env(env) { + env.parent().announce(env.ep().manage(root)); + } + + void _handle_signal() { + Genode::log("Signal received!"); + } +}; + +void Component::construct(Genode::Env &env) { + static Signals::Main main(env); +} diff --git a/src/signals/server/target.mk b/src/signals/server/target.mk new file mode 100644 index 0000000..f2be12d --- /dev/null +++ b/src/signals/server/target.mk @@ -0,0 +1,3 @@ +TARGET = signals_server +SRC_CC = main.cc +LIBS = base