libc: dispatch pending signals at selective points

This commit is contained in:
Christian Helmuth 2017-05-18 16:04:21 +02:00
parent 491be000ca
commit b1c9db8a0d
6 changed files with 61 additions and 6 deletions

View File

@ -118,6 +118,7 @@ class Genode::Entrypoint : Genode::Noncopyable
void _defer_signal(Signal &sig);
void _process_deferred_signals();
void _process_incoming_signals();
bool _wait_and_dispatch_one_io_signal(bool dont_block);
Constructible<Signal_proxy_thread> _signal_proxy_thread;
@ -180,7 +181,21 @@ class Genode::Entrypoint : Genode::Noncopyable
* receiver belongs to the calling entrypoint. Alternatively,
* remove it.
*/
void wait_and_dispatch_one_io_signal();
void wait_and_dispatch_one_io_signal()
{
_wait_and_dispatch_one_io_signal(false);
}
/**
* Dispatch single pending I/O-level signal (non-blocking)
*
* \return true if a pending signal was dispatched, false if no signal
* was pending
*/
bool dispatch_pending_io_signal()
{
return _wait_and_dispatch_one_io_signal(true);
}
/**
* Return RPC entrypoint

View File

@ -59,7 +59,7 @@ _ZN6Genode10Entrypoint16_dispatch_signalERNS_6SignalE T
_ZN6Genode10Entrypoint16schedule_suspendEPFvvES2_ T
_ZN6Genode10Entrypoint22Signal_proxy_component6signalEv T
_ZN6Genode10Entrypoint25_process_incoming_signalsEv T
_ZN6Genode10Entrypoint31wait_and_dispatch_one_io_signalEv T
_ZN6Genode10Entrypoint32_wait_and_dispatch_one_io_signalEb T
_ZN6Genode10Entrypoint6manageERNS_22Signal_dispatcher_baseE T
_ZN6Genode10Entrypoint8dissolveERNS_22Signal_dispatcher_baseE T
_ZN6Genode10EntrypointC1ERNS_3EnvE T

View File

@ -172,7 +172,7 @@ void Entrypoint::_process_incoming_signals()
}
void Entrypoint::wait_and_dispatch_one_io_signal()
bool Entrypoint::_wait_and_dispatch_one_io_signal(bool const dont_block)
{
for (;;) {
@ -198,6 +198,11 @@ void Entrypoint::wait_and_dispatch_one_io_signal()
} catch (Signal_receiver::Signal_not_pending) {
_signal_pending_lock.unlock();
if (dont_block) {
/* indicate that we leave wait_and_dispatch_one_io_signal */
cmpxchg(&_signal_recipient, ENTRYPOINT, NONE);
return false;
}
_sig_rec->block_for_signal();
}
}
@ -212,6 +217,8 @@ void Entrypoint::wait_and_dispatch_one_io_signal()
&Entrypoint::_handle_deferred_signals);
Signal_transmitter(*_deferred_signal_handler).submit();
}
return true;
}

View File

@ -389,7 +389,8 @@ struct Libc::Kernel
jmp_buf _kernel_context;
jmp_buf _user_context;
bool _valid_user_context = false;
bool _valid_user_context = false;
bool _dispatch_pending_io_signals = false;
Genode::Thread &_myself { *Genode::Thread::myself() };
@ -566,7 +567,7 @@ struct Libc::Kernel
}
/*
* During the supension of the application code a nested
* During the suspension of the application code a nested
* Libc::with_libc() call took place, which will be executed
* before returning to the first Libc::with_libc() call.
*/
@ -624,7 +625,13 @@ struct Libc::Kernel
/* _setjmp() returned after _longjmp() - user context suspended */
while ((!_app_returned) && (!_suspend_scheduled)) {
_env.ep().wait_and_dispatch_one_io_signal();
if (_dispatch_pending_io_signals) {
/* dispatch pending signals but don't block */
while (_env.ep().dispatch_pending_io_signal()) ;
} else {
/* block for signals */
_env.ep().wait_and_dispatch_one_io_signal();
}
if (_resume_main_once && !_setjmp(_kernel_context))
_switch_to_user();
@ -686,6 +693,21 @@ struct Libc::Kernel
: _pthreads.suspend_myself(check, timeout_ms);
}
void dispatch_pending_io_signals()
{
if (!_main_context()) return;
if (!_setjmp(_user_context)) {
_valid_user_context = true;
_dispatch_pending_io_signals = true;
_resume_main_once = true; /* afterwards resume main */
_switch_to_kernel();
} else {
_valid_user_context = false;
_dispatch_pending_io_signals = false;
}
}
unsigned long current_time()
{
return _timer_accessor.timer().curr_time();
@ -812,6 +834,13 @@ unsigned long Libc::suspend(Suspend_functor &s, unsigned long timeout_ms)
return kernel->suspend(s, timeout_ms);
}
void Libc::dispatch_pending_io_signals()
{
kernel->dispatch_pending_io_signals();
}
unsigned long Libc::current_time()
{
return kernel->current_time();

View File

@ -46,6 +46,8 @@ namespace Libc {
struct Suspend_functor { virtual bool suspend() = 0; };
unsigned long suspend(Suspend_functor &, unsigned long timeout_ms = 0UL);
void dispatch_pending_io_signals();
/**
* Get time since startup in ms
*/

View File

@ -446,6 +446,8 @@ ssize_t Libc::Vfs_plugin::write(Libc::File_descriptor *fd, const void *buf,
ssize_t Libc::Vfs_plugin::read(Libc::File_descriptor *fd, void *buf,
::size_t count)
{
Libc::dispatch_pending_io_signals();
typedef Vfs::File_io_service::Read_result Result;
Vfs::Vfs_handle *handle = vfs_handle(fd);