lx_kit: use central signal handler for scheduling

This commit extends the Lx_kit initialization function by passing in
a signal handler that is used to perform the normally occurring
scheduler execution and is a follow-up change for the decoupling
scheduler execution commit.

Instead of burying the signal handler in the 'Lx_kit::Scheduler'
object it is provided by the main object where the driver is free
to perform any additional step before or after executing the scheduler.

Issue #4927
Fixes #4952
This commit is contained in:
Josef Söntgen 2023-07-06 13:02:04 +02:00 committed by Norman Feske
parent dd1b8a106f
commit e18c02991e
12 changed files with 85 additions and 74 deletions

View File

@ -50,7 +50,7 @@ class Wireguard::Main : private Entrypoint::Io_progress_handler,
Heap _heap { _env.ram(), _env.rm() }; Heap _heap { _env.ram(), _env.rm() };
Attached_rom_dataspace _config_rom { _env, "config" }; Attached_rom_dataspace _config_rom { _env, "config" };
Signal_handler<Main> _config_handler { _env.ep(), *this, &Main::_handle_config }; Signal_handler<Main> _config_handler { _env.ep(), *this, &Main::_handle_config };
Io_signal_handler<Main> _signal_handler { _env.ep(), *this, &Main::_handle_signal }; Signal_handler<Main> _signal_handler { _env.ep(), *this, &Main::_handle_signal };
Config_model _config_model { _heap }; Config_model _config_model { _heap };
Signal_handler<Main> _nic_ip_config_handler { _env.ep(), *this, &Main::_handle_nic_ip_config }; Signal_handler<Main> _nic_ip_config_handler { _env.ep(), *this, &Main::_handle_nic_ip_config };
Nic_connection _nic_connection { _env, _heap, _signal_handler, _config_rom.xml(), _timer, *this }; Nic_connection _nic_connection { _env, _heap, _signal_handler, _config_rom.xml(), _timer, *this };
@ -82,7 +82,7 @@ class Wireguard::Main : private Entrypoint::Io_progress_handler,
: :
_env(env) _env(env)
{ {
Lx_kit::initialize(_env); Lx_kit::initialize(_env, _signal_handler);
/* /*
* We have to call the static constructors because otherwise the * We have to call the static constructors because otherwise the

View File

@ -33,13 +33,15 @@ namespace Lx_kit {
* *
* \param env - pointer to Genode::Env used to construct object initially * \param env - pointer to Genode::Env used to construct object initially
*/ */
Env & env(Genode::Env * env = nullptr); Env & env();
} }
struct Lx_kit::Env struct Lx_kit::Env
{ {
Genode::Env & env; Genode::Env & env;
Genode::Signal_context &_signal_dispatcher;
Genode::Heap heap { env.ram(), env.rm() }; Genode::Heap heap { env.ram(), env.rm() };
Initcalls initcalls { heap }; Initcalls initcalls { heap };
Pci_fixup_calls pci_fixup_calls { heap }; Pci_fixup_calls pci_fixup_calls { heap };
@ -52,7 +54,12 @@ struct Lx_kit::Env
Device_list devices { env.ep(), heap, platform }; Device_list devices { env.ep(), heap, platform };
Lx_kit::Timeout timeout { timer, scheduler }; Lx_kit::Timeout timeout { timer, scheduler };
Env(Genode::Env & env) : env(env) { } static void initialize(Genode::Env & env, Genode::Signal_context & sig_ctx);
Env(Genode::Env & env, Genode::Signal_context & sig_ctx)
: env(env), _signal_dispatcher(sig_ctx) { }
void submit_signal();
}; };
#endif /* _LX_KIT__ENV_H_ */ #endif /* _LX_KIT__ENV_H_ */

View File

@ -16,11 +16,12 @@
#include <base/env.h> #include <base/env.h>
#include <base/heap.h> #include <base/heap.h>
#include <base/signal.h>
namespace Lx_kit { namespace Lx_kit {
using namespace Genode; using namespace Genode;
void initialize(Env & env); void initialize(Env & env, Genode::Signal_context & sig_ctx);
class Initcalls; class Initcalls;
class Pci_fixup_calls; class Pci_fixup_calls;

View File

@ -43,9 +43,7 @@ class Lx_kit::Scheduler
void _idle_pre_post_process(); void _idle_pre_post_process();
void _schedule(); void _execute();
Signal_handler<Scheduler> _execute_schedule;
Genode::Fifo<Lx_kit::Pending_irq> _pending_irqs { }; Genode::Fifo<Lx_kit::Pending_irq> _pending_irqs { };
@ -60,7 +58,7 @@ class Lx_kit::Scheduler
void add(Task & task); void add(Task & task);
void remove(Task & task); void remove(Task & task);
void schedule() { _execute_schedule.local_submit(); } void schedule();
void execute(); void execute();
@ -78,12 +76,7 @@ class Lx_kit::Scheduler
template <typename FN> template <typename FN>
void for_each_task(FN const & fn); void for_each_task(FN const & fn);
Scheduler(Genode::Entrypoint &ep) Scheduler(Genode::Entrypoint &ep) : _ep { ep } { }
:
_ep { ep },
_execute_schedule { _ep, *this,
&Scheduler::_schedule }
{ }
}; };

View File

@ -14,8 +14,30 @@
#include <lx_kit/env.h> #include <lx_kit/env.h>
Lx_kit::Env & Lx_kit::env(Genode::Env * env) static Lx_kit::Env *_env_ptr;
void Lx_kit::Env::initialize(Genode::Env & env,
Genode::Signal_context & sig_ctx)
{ {
static Lx_kit::Env environment(*env); static Lx_kit::Env environment(env, sig_ctx);
return environment; _env_ptr = &environment;
}
Lx_kit::Env & Lx_kit::env()
{
if (!_env_ptr) {
Genode::error("Lx_kit::Env not initialized");
struct Env_not_initialized { };
throw Env_not_initialized();
}
return *_env_ptr;
}
void Lx_kit::Env::submit_signal()
{
_signal_dispatcher.local_submit();
} }

View File

@ -55,7 +55,7 @@ void Lx_kit::Pci_fixup_calls::execute(struct pci_dev *pci_dev)
} }
void Lx_kit::initialize(Genode::Env & env) void Lx_kit::initialize(Genode::Env & env, Genode::Signal_context & sig_ctx)
{ {
Lx_kit::env(&env); Lx_kit::Env::initialize(env, sig_ctx);
} }

View File

@ -116,7 +116,7 @@ void Scheduler::execute()
Genode::sleep_forever(); Genode::sleep_forever();
} }
_schedule(); _execute();
} }
@ -124,7 +124,7 @@ void Scheduler::execute()
* This signal handler function must only be called from within an EP * This signal handler function must only be called from within an EP
* context, see check in 'execute()'. * context, see check in 'execute()'.
*/ */
void Scheduler::_schedule() void Scheduler::_execute()
{ {
_idle_pre_post_process(); _idle_pre_post_process();
@ -174,3 +174,9 @@ void Scheduler::_schedule()
/* clear current as no task is running */ /* clear current as no task is running */
_current = nullptr; _current = nullptr;
} }
void Scheduler::schedule()
{
Lx_kit::env().submit_signal();
}

View File

@ -244,17 +244,17 @@ void _wifi_report_mac_address(Net::Mac_address const &mac_address)
struct Wlan struct Wlan
{ {
Env &_env; Env &_env;
Io_signal_handler<Wlan> _signal_handler { _env.ep(), *this, Signal_handler<Wlan> _signal_handler { _env.ep(), *this,
&Wlan::_handle_signal }; &Wlan::_handle_signal };
Dtb_helper _dtb_helper { _env }; Dtb_helper _dtb_helper { _env };
void _handle_signal() void _handle_signal()
{ {
if (uplink_task_struct_ptr) { if (uplink_task_struct_ptr)
lx_emul_task_unblock(uplink_task_struct_ptr); lx_emul_task_unblock(uplink_task_struct_ptr);
Lx_kit::env().scheduler.schedule();
} Lx_kit::env().scheduler.execute();
genode_uplink_notify_peers(); genode_uplink_notify_peers();
} }
@ -265,7 +265,7 @@ struct Wlan
Wlan(Env &env) : _env { env } Wlan(Env &env) : _env { env }
{ {
Lx_kit::initialize(env); Lx_kit::initialize(env, _signal_handler);
genode_mac_address_reporter_init(env, Lx_kit::env().heap); genode_mac_address_reporter_init(env, Lx_kit::env().heap);

View File

@ -32,9 +32,17 @@ struct Test::Driver
{ {
Env &env; Env &env;
Signal_handler<Driver> _signal_handler {
env.ep(), *this, &Driver::_handle_signal };
void _handle_signal()
{
Lx_kit::env().scheduler.execute();
}
Driver(Env &env) : env(env) Driver(Env &env) : env(env)
{ {
Lx_kit::initialize(env); Lx_kit::initialize(env, _signal_handler);
env.exec_static_constructors(); env.exec_static_constructors();

View File

@ -52,6 +52,8 @@ struct Framebuffer::Driver
&Driver::config_update }; &Driver::config_update };
Signal_handler<Driver> timer_handler { env.ep(), *this, Signal_handler<Driver> timer_handler { env.ep(), *this,
&Driver::handle_timer }; &Driver::handle_timer };
Signal_handler<Driver> scheduler_handler { env.ep(), *this,
&Driver::handle_scheduler };
bool update_in_progress { false }; bool update_in_progress { false };
bool new_config_rom { false }; bool new_config_rom { false };
@ -109,9 +111,14 @@ struct Framebuffer::Driver
if (fb.constructed()) { fb->paint(); } if (fb.constructed()) { fb->paint(); }
} }
void handle_scheduler()
{
Lx_kit::env().scheduler.execute();
}
Driver(Env &env) : env(env) Driver(Env &env) : env(env)
{ {
Lx_kit::initialize(env); Lx_kit::initialize(env, scheduler_handler);
env.exec_static_constructors(); env.exec_static_constructors();
config.sigh(config_handler); config.sigh(config_handler);

View File

@ -28,20 +28,12 @@ namespace Pc {
extern task_struct *user_task_struct_ptr; extern task_struct *user_task_struct_ptr;
struct Pc::Main : private Entrypoint::Io_progress_handler struct Pc::Main
{ {
Env &_env; Env &_env;
Attached_rom_dataspace _config { _env, "config" }; Attached_rom_dataspace _config { _env, "config" };
/**
* Entrypoint::Io_progress_handler
*/
void handle_io_progress() override
{
genode_uplink_notify_peers();
}
/** /**
* Config update signal handler * Config update signal handler
*/ */
@ -56,36 +48,21 @@ struct Pc::Main : private Entrypoint::Io_progress_handler
/** /**
* Signal handler triggered by activity of the uplink connection * Signal handler triggered by activity of the uplink connection
*/ */
Io_signal_handler<Main> _signal_handler { _env.ep(), *this, &Main::_handle_signal }; Signal_handler<Main> _signal_handler { _env.ep(), *this, &Main::_handle_signal };
unsigned _signal_handler_nesting_level = 0;
void _handle_signal() void _handle_signal()
{ {
_signal_handler_nesting_level++; if (user_task_struct_ptr)
{
if (!user_task_struct_ptr)
return;
lx_emul_task_unblock(user_task_struct_ptr); lx_emul_task_unblock(user_task_struct_ptr);
Lx_kit::env().scheduler.schedule();
}
/* Lx_kit::env().scheduler.execute();
* Process currently pending I/O signals before leaving the signal
* handler to limit the rate of 'handle_io_progress' calls.
*/
if (_signal_handler_nesting_level == 1) {
while (_env.ep().dispatch_pending_io_signal());
}
_signal_handler_nesting_level--; genode_uplink_notify_peers();
} }
Main(Env &env) : _env(env) Main(Env &env) : _env(env)
{ {
Lx_kit::initialize(env); Lx_kit::initialize(env, _signal_handler);
env.exec_static_constructors(); env.exec_static_constructors();
@ -100,8 +77,6 @@ struct Pc::Main : private Entrypoint::Io_progress_handler
_handle_config(); _handle_config();
lx_emul_start_kernel(nullptr); lx_emul_start_kernel(nullptr);
env.ep().register_io_progress_handler(*this);
} }
}; };

View File

@ -43,25 +43,19 @@ extern "C" int inhibit_pci_fixup(char const *name)
} }
struct Main : private Entrypoint::Io_progress_handler struct Main
{ {
Env & env; Env & env;
Signal_handler<Main> signal_handler { env.ep(), *this, Signal_handler<Main> signal_handler { env.ep(), *this,
&Main::handle_signal }; &Main::handle_signal };
Sliced_heap sliced_heap { env.ram(), env.rm() }; Sliced_heap sliced_heap { env.ram(), env.rm() };
/**
* Entrypoint::Io_progress_handler
*/
void handle_io_progress() override
{
genode_usb_notify_peers();
}
void handle_signal() void handle_signal()
{ {
lx_user_handle_io(); lx_user_handle_io();
Lx_kit::env().scheduler.execute(); Lx_kit::env().scheduler.execute();
genode_usb_notify_peers();
} }
Main(Env & env) : env(env) Main(Env & env) : env(env)
@ -72,7 +66,7 @@ struct Main : private Entrypoint::Io_progress_handler
_bios_handoff = config.rom.xml().attribute_value("bios_handoff", true); _bios_handoff = config.rom.xml().attribute_value("bios_handoff", true);
} }
Lx_kit::initialize(env); Lx_kit::initialize(env, signal_handler);
env.exec_static_constructors(); env.exec_static_constructors();
genode_usb_init(genode_env_ptr(env), genode_usb_init(genode_env_ptr(env),
@ -81,8 +75,6 @@ struct Main : private Entrypoint::Io_progress_handler
&lx_emul_usb_rpc_callbacks); &lx_emul_usb_rpc_callbacks);
lx_emul_start_kernel(nullptr); lx_emul_start_kernel(nullptr);
env.ep().register_io_progress_handler(*this);
} }
}; };