genode/repos/base/src/core/pager_ep.cc
Stefan Kalkowski eafe5e81e3 core: unify and simplify paging code (Fix #1641)
For most platforms except of NOVA a distinction between pager entrypoint
and pager activation is not needed, and only exists due to historical
reasons. Moreover, the pager thread's execution path is almost identical
between most platforms excluding NOVA, HW, and Fisco.OC. Therefore,
this commit unifies the pager loop for the other platforms, and removes
the pager activation class.
2015-08-21 10:58:59 +02:00

104 lines
2.5 KiB
C++

/*
* \brief Generic implmentation of pager entrypoint
* \author Norman Feske
* \author Stefan Kalkowski
* \date 2009-03-31
*/
/*
* Copyright (C) 2009-2015 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/* Core includes */
#include <pager.h>
using namespace Genode;
void Pager_entrypoint::entry()
{
bool reply_pending = false;
while (1) {
if (reply_pending)
_pager.reply_and_wait_for_fault();
else
_pager.wait_for_fault();
reply_pending = false;
/* lookup referenced object */
Object_pool<Pager_object>::Guard _obj(lookup_and_lock(_pager.badge()));
Pager_object *obj = _obj;
/* handle request */
if (obj) {
if (_pager.is_exception()) {
obj->submit_exception_signal();
continue;
}
/* send reply if page-fault handling succeeded */
reply_pending = !obj->pager(_pager);
continue;
} else {
/*
* Prevent threads outside of core to mess with our wake-up
* interface. This condition can trigger if a process gets
* destroyed which triggered a page fault shortly before getting
* killed. In this case, 'wait_for_fault()' returns (because of
* the page fault delivery) but the pager-object lookup will fail
* (because core removed the process already).
*/
if (_pager.request_from_core()) {
/*
* We got a request from one of cores region-manager sessions
* to answer the pending page fault of a resolved region-manager
* client. Hence, we have to send the page-fault reply to the
* specified thread and answer the call of the region-manager
* session.
*
* When called from a region-manager session, we receive the
* core-local address of the targeted pager object via the
* first message word, which corresponds to the 'fault_ip'
* argument of normal page-fault messages.
*/
obj = reinterpret_cast<Pager_object *>(_pager.fault_ip());
/* send reply to the calling region-manager session */
_pager.acknowledge_wakeup();
/* answer page fault of resolved pager object */
_pager.set_reply_dst(obj->cap());
_pager.acknowledge_wakeup();
}
}
};
}
void Pager_entrypoint::dissolve(Pager_object *obj)
{
remove_locked(obj);
}
Pager_capability Pager_entrypoint::manage(Pager_object *obj)
{
Native_capability cap = _manage(obj);
/* add server object to object pool */
obj->cap(cap);
insert(obj);
/* return capability that uses the object id as badge */
return reinterpret_cap_cast<Pager_object>(cap);
}