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;
}