diff --git a/base-hw/include/base/pager.h b/base-hw/include/base/pager.h index afeb4f3546..f0924927ff 100644 --- a/base-hw/include/base/pager.h +++ b/base-hw/include/base/pager.h @@ -20,6 +20,9 @@ #include #include +/* base-hw includes */ +#include + namespace Genode { class Cap_session; @@ -132,9 +135,38 @@ class Genode::Pager_object : public Object_pool::Entry, Signal_context_capability _signal_context_cap; Thread_capability _thread_cap; + bool _signal_valid; char _signal_buf[sizeof(Signal)]; unsigned const _badge; + /** + * Remember an incoming fault for handling + * + * \param s fault signal + */ + void _take_fault(Signal const & s) + { + new (_signal_buf) Signal(s); + _signal_valid = 1; + } + + /** + * End handling of current fault + */ + void _end_fault() + { + _signal()->~Signal(); + _signal_valid = 0; + } + + /** + * End handling of current fault if there is one + */ + void _end_fault_if_pending() + { + if (_signal_valid) { _end_fault(); } + } + /*************** ** Accessors ** @@ -151,27 +183,22 @@ class Genode::Pager_object : public Object_pool::Entry, */ Pager_object(unsigned const badge, Affinity::Location); - /** - * Destructor - */ - virtual ~Pager_object() { } - /** * The faulter has caused a fault and awaits paging * * \param s signal that communicated the fault */ - void fault_occured(Signal const & s); + void fault_occured(Signal const & s) { _take_fault(s); } /** * Current fault has been resolved so resume faulter */ - void fault_resolved(); + void fault_resolved() { _end_fault(); } /** * User identification of pager object */ - unsigned badge() const; + unsigned badge() const { return _badge; } /** * Resume faulter @@ -183,6 +210,29 @@ class Genode::Pager_object : public Object_pool::Entry, */ void exception_handler(Signal_context_capability); + /** + * Install information that is necessary to handle page faults + * + * \param c linkage between signal context and a signal receiver + * \param p linkage between pager object and a pager entry-point + */ + void start_paging(Signal_context_capability const & c, + Pager_capability const & p) + { + _signal_context_cap = c; + Object_pool::Entry::cap(p); + } + + /** + * Uninstall paging information and cancel unresolved faults + */ + void stop_paging() + { + Object_pool::Entry::cap(Native_capability()); + _signal_context_cap = Signal_context_capability(); + _end_fault_if_pending(); + } + /****************** ** Pure virtual ** @@ -207,8 +257,6 @@ class Genode::Pager_object : public Object_pool::Entry, void thread_cap(Thread_capability const & c); - void cap(Native_capability const & c); - unsigned signal_context_id() const; }; diff --git a/base-hw/src/base/pager.cc b/base-hw/src/base/pager.cc index a0916af243..f1b045613a 100644 --- a/base-hw/src/base/pager.cc +++ b/base-hw/src/base/pager.cc @@ -15,9 +15,6 @@ #include #include -/* base-hw includes */ -#include - using namespace Genode; @@ -70,25 +67,10 @@ void Pager_object::wake_up() { fault_resolved(); } void Pager_object::exception_handler(Signal_context_capability) { } -void Pager_object::fault_resolved() { _signal()->~Signal(); } - -unsigned Pager_object::badge() const { return _badge; } - - -void Pager_object::fault_occured(Signal const & s) -{ - new (_signal()) Signal(s); -} - - -void Pager_object::cap(Native_capability const & c) -{ - Object_pool::Entry::cap(c); -} - Pager_object::Pager_object(unsigned const badge, Affinity::Location) : + _signal_valid(0), _badge(badge) { } @@ -126,12 +108,8 @@ Native_capability Pager_activation_base::cap() void Pager_entrypoint::dissolve(Pager_object * const o) { - /* let entrypoint dissolve the pager object */ remove_locked(o); - o->cap(Native_capability()); - - /* let activation signal-receiver dissolve the pager signal-context */ - o->_signal_context_cap = Signal_context_capability(); + o->stop_paging(); _activation->Signal_receiver::dissolve(o); } @@ -147,13 +125,10 @@ Pager_entrypoint::Pager_entrypoint(Cap_session *, Pager_capability Pager_entrypoint::manage(Pager_object * const o) { - /* let activation signal-receiver manage the pager signal-context */ - o->_signal_context_cap = _activation->Signal_receiver::manage(o); - - /* let entrypoint manage the pager object */ - unsigned const dst = _activation->cap().dst(); - Native_capability c = Native_capability(dst, o->badge()); - o->cap(c); + unsigned const d = _activation->cap().dst(); + unsigned const b = o->badge(); + auto const p = reinterpret_cap_cast(Native_capability(d, b)); + o->start_paging(_activation->Signal_receiver::manage(o), p); insert(o); - return reinterpret_cap_cast(c); + return p; }