mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 17:52:52 +00:00
base: replace obj_by_* by lookup_and_lock
Add functionality to lookup an object and lock it. Additional the case is handled that a object may be already in-destruction and the lookup will deny returning the object. The object_pool generalize the lookup and lock functionality of the rpc_server and serve as base for following up patches to fix dangling pointer issues.
This commit is contained in:
parent
ca37f26a01
commit
c2d3543e62
@ -27,43 +27,47 @@ void Pager_activation_base::entry()
|
||||
_cap = pager;
|
||||
_cap_valid.unlock();
|
||||
|
||||
pager.wait_for_fault();
|
||||
bool reply = false;
|
||||
|
||||
while (1) {
|
||||
|
||||
if (reply)
|
||||
pager.reply_and_wait_for_fault();
|
||||
else
|
||||
pager.wait_for_fault();
|
||||
|
||||
/* lookup referenced object */
|
||||
Pager_object *obj = _ep ? _ep->obj_by_id(pager.badge()) : 0;
|
||||
Object_pool<Pager_object>::Guard _obj(_ep ? _ep->lookup_and_lock(pager.badge()) : 0);
|
||||
Pager_object * obj = _obj;
|
||||
reply = false;
|
||||
|
||||
/* handle request */
|
||||
if (obj) {
|
||||
if (obj->pager(pager))
|
||||
/* something strange occured - leave thread in pagefault */
|
||||
pager.wait_for_fault();
|
||||
else
|
||||
pager.reply_and_wait_for_fault();
|
||||
} else {
|
||||
|
||||
/*
|
||||
* 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();
|
||||
pager.wait_for_fault();
|
||||
reply = !obj->pager(pager);
|
||||
/* something strange occurred - leave thread in pagefault */
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +83,7 @@ Pager_entrypoint::Pager_entrypoint(Cap_session *, Pager_activation_base *a)
|
||||
|
||||
void Pager_entrypoint::dissolve(Pager_object *obj)
|
||||
{
|
||||
remove(obj);
|
||||
remove_locked(obj);
|
||||
}
|
||||
|
||||
|
||||
|
@ -30,7 +30,7 @@ Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
|
||||
{
|
||||
using namespace Codezero;
|
||||
|
||||
Dataspace_component *ds = static_cast<Dataspace_component *>(_ds_ep->obj_by_cap(ds_cap));
|
||||
Object_pool<Dataspace_component>::Guard ds(_ds_ep->lookup_and_lock(ds_cap));
|
||||
if (!ds)
|
||||
throw Invalid_dataspace();
|
||||
|
||||
|
@ -34,19 +34,26 @@ void Pager_activation_base::entry()
|
||||
_cap = pager;
|
||||
_cap_valid.unlock();
|
||||
|
||||
pager.wait_for_fault();
|
||||
Pager_object * obj;
|
||||
bool reply = false;
|
||||
|
||||
while (1) {
|
||||
|
||||
if (reply)
|
||||
pager.reply_and_wait_for_fault();
|
||||
else
|
||||
pager.wait_for_fault();
|
||||
|
||||
/* lookup referenced object */
|
||||
Pager_object *obj = _ep ? _ep->obj_by_id(pager.badge()) : 0;
|
||||
Object_pool<Pager_object>::Guard _obj(_ep ? _ep->lookup_and_lock(pager.badge()) : 0);
|
||||
obj = _obj;
|
||||
reply = false;
|
||||
|
||||
/* handle request */
|
||||
if (obj) {
|
||||
if (obj->pager(pager))
|
||||
/* something strange occured - leave thread in pagefault */
|
||||
pager.wait_for_fault();
|
||||
else
|
||||
pager.reply_and_wait_for_fault();
|
||||
reply = !obj->pager(pager);
|
||||
/* something strange occurred - leave thread in pagefault */
|
||||
continue;
|
||||
} else {
|
||||
|
||||
/* prevent threads outside of core to mess with our wake-up interface */
|
||||
@ -79,7 +86,6 @@ void Pager_activation_base::entry()
|
||||
pager.set_reply_dst(obj->cap());
|
||||
pager.acknowledge_wakeup();
|
||||
}
|
||||
pager.wait_for_fault();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -96,7 +102,7 @@ Pager_entrypoint::Pager_entrypoint(Cap_session *, Pager_activation_base *a)
|
||||
|
||||
void Pager_entrypoint::dissolve(Pager_object *obj)
|
||||
{
|
||||
remove(obj);
|
||||
remove_locked(obj);
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,7 +56,7 @@ void Pager_activation_base::entry()
|
||||
}
|
||||
|
||||
/* lookup referenced object */
|
||||
Pager_object *obj = _ep->obj_by_id(pager.badge());
|
||||
Object_pool<Pager_object>::Guard obj(_ep->lookup_and_lock(pager.badge()));
|
||||
|
||||
/* the pager_object might be destroyed, while we got the message */
|
||||
if (!obj) {
|
||||
@ -165,7 +165,7 @@ void Pager_entrypoint::dissolve(Pager_object *obj)
|
||||
/* cleanup at cap session */
|
||||
_cap_session->free(obj->Object_pool<Pager_object>::Entry::cap());
|
||||
|
||||
remove(obj);
|
||||
remove_locked(obj);
|
||||
}
|
||||
|
||||
|
||||
|
@ -71,22 +71,23 @@ void Rpc_entrypoint::entry()
|
||||
}
|
||||
|
||||
/* atomically lookup and lock referenced object */
|
||||
Object_pool<Rpc_object_base>::Guard curr_obj(lookup_and_lock(srv.badge()));
|
||||
if (!curr_obj)
|
||||
continue;
|
||||
|
||||
{
|
||||
Lock::Guard lock_guard(_curr_obj_lock);
|
||||
|
||||
_curr_obj = obj_by_id(srv.badge());
|
||||
if (!_curr_obj)
|
||||
continue;
|
||||
|
||||
_curr_obj->lock();
|
||||
_curr_obj = curr_obj;
|
||||
}
|
||||
|
||||
/* dispatch request */
|
||||
try { srv.ret(_curr_obj->dispatch(opcode, srv, srv)); }
|
||||
catch (Blocking_canceled) { }
|
||||
|
||||
_curr_obj->unlock();
|
||||
_curr_obj = 0;
|
||||
{
|
||||
Lock::Guard lock_guard(_curr_obj_lock);
|
||||
_curr_obj = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* answer exit call, thereby wake up '~Rpc_entrypoint' */
|
||||
|
@ -40,9 +40,7 @@ void Genode::Cpu_session_component::enable_vcpu(Genode::Thread_capability thread
|
||||
using namespace Genode;
|
||||
using namespace Fiasco;
|
||||
|
||||
Lock::Guard lock_guard(_thread_list_lock);
|
||||
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return;
|
||||
|
||||
Native_thread tid = thread->platform_thread()->thread().local.dst();
|
||||
@ -58,9 +56,7 @@ Genode::Cpu_session_component::native_cap(Genode::Thread_capability cap)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Lock::Guard lock_guard(_thread_list_lock);
|
||||
|
||||
Cpu_thread_component *thread = _lookup_thread(cap);
|
||||
Object_pool<Cpu_thread_component>::Guard thread(_thread_ep->lookup_and_lock(cap));
|
||||
if (!thread) return Native_capability();
|
||||
|
||||
return thread->platform_thread()->thread().local;
|
||||
@ -101,9 +97,7 @@ void Genode::Cpu_session_component::single_step(Genode::Thread_capability thread
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Lock::Guard lock_guard(_thread_list_lock);
|
||||
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return;
|
||||
|
||||
Native_thread tid = thread->platform_thread()->thread().local.dst();
|
||||
|
@ -110,16 +110,6 @@ namespace Genode {
|
||||
*/
|
||||
Signal_context_capability _default_exception_handler;
|
||||
|
||||
/**
|
||||
* Lookup thread in CPU session by its capability
|
||||
*
|
||||
* \retval NULL thread capability is invalid or
|
||||
* does not belong to the CPU session
|
||||
*/
|
||||
Cpu_thread_component *_lookup_thread(Thread_capability thread) {
|
||||
return dynamic_cast<Cpu_thread_component *>
|
||||
(_thread_ep->obj_by_cap(thread)); }
|
||||
|
||||
/**
|
||||
* Raw thread-killing functionality
|
||||
*
|
||||
|
@ -30,18 +30,22 @@ void Pager_activation_base::entry()
|
||||
_cap_valid.unlock();
|
||||
|
||||
/* wait for the first pagefault */
|
||||
pager.wait_for_fault();
|
||||
bool reply = false;
|
||||
while (1)
|
||||
{
|
||||
if (reply)
|
||||
pager.resolve_and_wait_for_fault();
|
||||
else
|
||||
pager.wait_for_fault();
|
||||
|
||||
/* lookup pager object for the current faulter */
|
||||
Pager_object * o = _ep ? _ep->obj_by_id(pager.badge()) : 0;
|
||||
Object_pool<Pager_object>::Guard o(_ep ? _ep->lookup_and_lock(pager.badge()) : 0);
|
||||
if (!o) {
|
||||
PERR("%s:%d: Invalid pager object", __FILE__, __LINE__);
|
||||
while (1) ;
|
||||
}
|
||||
/* let pager handle the pagefault, apply mapping, await pagefault */
|
||||
if (o->pager(pager)) pager.wait_for_fault();
|
||||
else pager.resolve_and_wait_for_fault();
|
||||
reply = !o->pager(pager);
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,7 +59,7 @@ Pager_entrypoint::Pager_entrypoint(Cap_session *,
|
||||
: _activation(a) { _activation->ep(this); }
|
||||
|
||||
|
||||
void Pager_entrypoint::dissolve(Pager_object * const o) { remove(o); }
|
||||
void Pager_entrypoint::dissolve(Pager_object * const o) { remove_locked(o); }
|
||||
|
||||
|
||||
Pager_capability Pager_entrypoint::manage(Pager_object * const o)
|
||||
|
@ -23,11 +23,9 @@ using namespace Genode;
|
||||
Ram_dataspace_capability
|
||||
Cpu_session_component::utcb(Thread_capability thread_cap)
|
||||
{
|
||||
/* serialize access */
|
||||
Lock::Guard lock_guard(_thread_list_lock);
|
||||
|
||||
/* lookup requested UTCB dataspace */
|
||||
Cpu_thread_component * t = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard
|
||||
t(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!t) return Ram_dataspace_capability();
|
||||
return t->platform_thread()->utcb();
|
||||
}
|
||||
|
@ -40,6 +40,9 @@ namespace Genode {
|
||||
*/
|
||||
Thread_capability thread_cap() { return _thread_cap; } const
|
||||
void thread_cap(Thread_capability cap) { _thread_cap = cap; }
|
||||
|
||||
/* required by lookup_and_lock, provided by Object_pool::Entry normally */
|
||||
void release() { }
|
||||
};
|
||||
|
||||
class Pager_activation_base { };
|
||||
@ -47,7 +50,7 @@ namespace Genode {
|
||||
{
|
||||
Pager_entrypoint(Cap_session *, Pager_activation_base *) { }
|
||||
|
||||
Pager_object *obj_by_cap(Pager_capability) { return 0; }
|
||||
Pager_object *lookup_and_lock(Pager_capability) { return 0; }
|
||||
};
|
||||
template <int FOO> class Pager_activation : public Pager_activation_base { };
|
||||
}
|
||||
|
@ -15,9 +15,8 @@ using namespace Genode;
|
||||
|
||||
void Cpu_session_component::thread_id(Thread_capability thread_cap, int pid, int tid)
|
||||
{
|
||||
Lock::Guard lock_guard(_thread_list_lock);
|
||||
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard
|
||||
thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return;
|
||||
|
||||
thread->platform_thread()->thread_id(pid, tid);
|
||||
@ -26,9 +25,8 @@ void Cpu_session_component::thread_id(Thread_capability thread_cap, int pid, int
|
||||
|
||||
Untyped_capability Cpu_session_component::server_sd(Thread_capability thread_cap)
|
||||
{
|
||||
Lock::Guard lock_guard(_thread_list_lock);
|
||||
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard
|
||||
thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return Untyped_capability();
|
||||
|
||||
enum { DUMMY_LOCAL_NAME = 0 };
|
||||
@ -40,9 +38,8 @@ Untyped_capability Cpu_session_component::server_sd(Thread_capability thread_cap
|
||||
|
||||
Untyped_capability Cpu_session_component::client_sd(Thread_capability thread_cap)
|
||||
{
|
||||
Lock::Guard lock_guard(_thread_list_lock);
|
||||
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard
|
||||
thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return Untyped_capability();
|
||||
|
||||
enum { DUMMY_LOCAL_NAME = 0 };
|
||||
|
@ -126,13 +126,6 @@ namespace Genode {
|
||||
{
|
||||
enum { STACK_SIZE = 2048 * sizeof(Genode::addr_t) };
|
||||
|
||||
template <typename T>
|
||||
T *lookup(Capability<T> cap)
|
||||
{
|
||||
Rpc_object_base *obj = obj_by_cap(cap);
|
||||
return obj ? dynamic_cast<T *>(obj) : 0;
|
||||
}
|
||||
|
||||
Entrypoint(Cap_session *cap_session)
|
||||
:
|
||||
Rpc_entrypoint(cap_session, STACK_SIZE, "entrypoint")
|
||||
|
@ -104,16 +104,6 @@ namespace Genode {
|
||||
*/
|
||||
Signal_context_capability _default_exception_handler;
|
||||
|
||||
/**
|
||||
* Lookup thread in CPU session by its capability
|
||||
*
|
||||
* \retval NULL thread capability is invalid or
|
||||
* does not belong to the CPU session
|
||||
*/
|
||||
Cpu_thread_component *_lookup_thread(Thread_capability thread) {
|
||||
return dynamic_cast<Cpu_thread_component *>
|
||||
(_thread_ep->obj_by_cap(thread)); }
|
||||
|
||||
/**
|
||||
* Raw thread-killing functionality
|
||||
*
|
||||
|
@ -365,8 +365,7 @@ int Pd_session_component::assign_parent(Parent_capability parent)
|
||||
void Pd_session_component::start(Capability<Dataspace> binary)
|
||||
{
|
||||
/* lookup binary dataspace */
|
||||
Dataspace_component *ds =
|
||||
reinterpret_cast<Dataspace_component *>(_ds_ep->obj_by_cap(binary));
|
||||
Object_pool<Dataspace_component>::Guard ds(_ds_ep->lookup_and_lock(binary));
|
||||
|
||||
if (!ds) {
|
||||
PERR("could not lookup binary, aborted PD startup");
|
||||
|
@ -161,7 +161,9 @@ Platform_env_base::Rm_session_mmap::_dataspace_size(Capability<Dataspace> ds_cap
|
||||
}
|
||||
|
||||
/* use local function call if called from the entrypoint */
|
||||
Dataspace *ds = core_env()->entrypoint()->lookup(ds_cap);
|
||||
Object_pool<Rpc_object_base>::Guard
|
||||
ds_rpc(core_env()->entrypoint()->lookup_and_lock(ds_cap));
|
||||
Dataspace * ds = dynamic_cast<Dataspace *>(&*ds_rpc);
|
||||
return ds ? ds->size() : 0;
|
||||
}
|
||||
|
||||
@ -178,7 +180,9 @@ int Platform_env_base::Rm_session_mmap::_dataspace_fd(Capability<Dataspace> ds_c
|
||||
|
||||
Capability<Linux_dataspace> lx_ds_cap = static_cap_cast<Linux_dataspace>(ds_cap);
|
||||
|
||||
Linux_dataspace *ds = core_env()->entrypoint()->lookup(lx_ds_cap);
|
||||
Object_pool<Rpc_object_base>::Guard
|
||||
ds_rpc(core_env()->entrypoint()->lookup_and_lock(lx_ds_cap));
|
||||
Linux_dataspace * ds = dynamic_cast<Linux_dataspace *>(&*ds_rpc);
|
||||
|
||||
return ds ? ds->fd().dst().socket : -1;
|
||||
}
|
||||
@ -194,7 +198,9 @@ bool Platform_env_base::Rm_session_mmap::_dataspace_writable(Dataspace_capabilit
|
||||
return writable;
|
||||
}
|
||||
|
||||
Dataspace *ds = core_env()->entrypoint()->lookup(ds_cap);
|
||||
Object_pool<Rpc_object_base>::Guard
|
||||
ds_rpc(core_env()->entrypoint()->lookup_and_lock(ds_cap));
|
||||
Dataspace * ds = dynamic_cast<Dataspace *>(&*ds_rpc);
|
||||
|
||||
return ds ? ds->writable() : false;
|
||||
}
|
||||
|
@ -29,30 +29,38 @@ void Pager_activation_base::entry()
|
||||
_cap_valid.unlock();
|
||||
|
||||
// PINF("Ready for page faults");
|
||||
pager.wait_for_fault();
|
||||
Pager_object * obj;
|
||||
bool reply = false;
|
||||
|
||||
while (1) {
|
||||
|
||||
if (reply)
|
||||
pager.reply_and_wait_for_fault();
|
||||
else
|
||||
pager.wait_for_fault();
|
||||
|
||||
/* lookup referenced object */
|
||||
Pager_object *obj = _ep ? _ep->obj_by_id(pager.badge()) : 0;
|
||||
Object_pool<Pager_object>::Guard _obj(_ep ? _ep->lookup_and_lock(pager.badge()) : 0);
|
||||
obj = _obj;
|
||||
reply = false;
|
||||
|
||||
/* handle request */
|
||||
if (obj) {
|
||||
// PINF("Pagefault request from a common pager object");
|
||||
|
||||
if (!pager.resolved()){
|
||||
if (obj->pager(pager)){
|
||||
/* something strange occured - leave thread in pagefault */
|
||||
// PINF("Leave unresolved, wait for next page fault");
|
||||
pager.wait_for_fault();
|
||||
}
|
||||
else{
|
||||
// PINF("Resolved, reply and wait for next page fault");
|
||||
pager.reply_and_wait_for_fault();
|
||||
}
|
||||
if (pager.resolved()) {
|
||||
reply = true;
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
pager.reply_and_wait_for_fault();
|
||||
|
||||
reply = !obj->pager(pager);
|
||||
if (!reply) {
|
||||
/* something strange occured - leave thread in pagefault */
|
||||
// PINF("Leave unresolved, wait for next page fault");
|
||||
} else {
|
||||
// PINF("Resolved, reply and wait for next page fault");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
// PINF("Pagefault request from one of cores region manager sessions");
|
||||
@ -79,7 +87,6 @@ void Pager_activation_base::entry()
|
||||
pager.acknowledge_wakeup();
|
||||
|
||||
// PINF("Wait for next page fault");
|
||||
pager.wait_for_fault();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -96,7 +103,7 @@ Pager_entrypoint::Pager_entrypoint(Cap_session *, Pager_activation_base *a)
|
||||
}
|
||||
|
||||
|
||||
void Pager_entrypoint::dissolve(Pager_object *obj) { remove(obj); }
|
||||
void Pager_entrypoint::dissolve(Pager_object *obj) { remove_locked(obj); }
|
||||
|
||||
|
||||
Pager_capability Pager_entrypoint::manage(Pager_object *obj)
|
||||
|
@ -28,7 +28,7 @@ Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
|
||||
Rm_session::Local_addr local_addr,
|
||||
bool executable)
|
||||
{
|
||||
Dataspace_component *ds = static_cast<Dataspace_component *>(_ds_ep->obj_by_cap(ds_cap));
|
||||
Object_pool<Dataspace_component>::Guard ds(_ds_ep->lookup_and_lock(ds_cap));
|
||||
if (!ds)
|
||||
throw Invalid_dataspace();
|
||||
|
||||
|
@ -352,6 +352,6 @@ void Pager_entrypoint::dissolve(Pager_object *obj)
|
||||
|
||||
cap_selector_allocator()->free(pager_pt.local_name(), 0);
|
||||
|
||||
remove(obj);
|
||||
remove_locked(obj);
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ void Rpc_entrypoint::_dissolve(Rpc_object_base *obj)
|
||||
Nova::revoke(Nova::Obj_crd(obj->cap().local_name(), 0), false);
|
||||
|
||||
/* make sure nobody is able to find this object */
|
||||
remove(obj);
|
||||
remove_locked(obj);
|
||||
|
||||
/*
|
||||
* The activation may execute a blocking operation
|
||||
@ -73,7 +73,7 @@ void Rpc_entrypoint::_dissolve(Rpc_object_base *obj)
|
||||
_leave_server_object(obj);
|
||||
|
||||
/* wait until nobody is inside dispatch */
|
||||
obj->lock();
|
||||
obj->acquire();
|
||||
|
||||
/* De-announce object from cap_session */
|
||||
_cap_session->free(obj->cap());
|
||||
@ -96,6 +96,13 @@ void Rpc_entrypoint::_activation_entry()
|
||||
|
||||
Rpc_entrypoint *ep = static_cast<Rpc_entrypoint *>(Thread_base::myself());
|
||||
|
||||
/* delay start if requested so */
|
||||
if (ep->_curr_obj) {
|
||||
ep->_delay_start.lock();
|
||||
ep->_delay_start.unlock();
|
||||
}
|
||||
|
||||
/* prepare ipc server object (copying utcb content to message buffer */
|
||||
Ipc_server srv(&ep->_snd_buf, &ep->_rcv_buf);
|
||||
ep->_rcv_buf.post_ipc(reinterpret_cast<Nova::Utcb *>(ep->utcb()));
|
||||
|
||||
@ -110,32 +117,34 @@ void Rpc_entrypoint::_activation_entry()
|
||||
srv.ret(ERR_INVALID_OBJECT);
|
||||
|
||||
/* atomically lookup and lock referenced object */
|
||||
Rpc_object_base * curr_obj = ep->lookup_and_lock(id_pt);
|
||||
{
|
||||
Lock::Guard lock_guard(ep->_curr_obj_lock);
|
||||
ep->_curr_obj = curr_obj;
|
||||
}
|
||||
if (!ep->_curr_obj) {
|
||||
/* Badge is used to suppress error message solely.
|
||||
* It's non zero during cleanup call of an
|
||||
* rpc_object_base object, see _leave_server_object.
|
||||
*/
|
||||
if (!srv.badge())
|
||||
PERR("could not look up server object, "
|
||||
" return from call id_pt=%lx",
|
||||
id_pt);
|
||||
|
||||
ep->_curr_obj = ep->obj_by_id(id_pt);
|
||||
if (!ep->_curr_obj || !id_pt) {
|
||||
/* Badge is used to suppress error message solely.
|
||||
* It's non zero during cleanup call of an
|
||||
* rpc_object_base object, see _leave_server_object.
|
||||
*/
|
||||
if (!srv.badge())
|
||||
PERR("could not look up server object, "
|
||||
" return from call id_pt=%lx",
|
||||
id_pt);
|
||||
ep->_curr_obj_lock.unlock();
|
||||
srv << IPC_REPLY;
|
||||
}
|
||||
|
||||
ep->_curr_obj->lock();
|
||||
srv << IPC_REPLY;
|
||||
}
|
||||
|
||||
/* dispatch request */
|
||||
try { srv.ret(ep->_curr_obj->dispatch(opcode, srv, srv)); }
|
||||
catch (Blocking_canceled) { }
|
||||
|
||||
ep->_curr_obj->unlock();
|
||||
ep->_curr_obj = 0;
|
||||
Rpc_object_base * tmp = ep->_curr_obj;
|
||||
{
|
||||
Lock::Guard lock_guard(ep->_curr_obj_lock);
|
||||
ep->_curr_obj = 0;
|
||||
}
|
||||
tmp->release();
|
||||
|
||||
ep->_rcv_buf.rcv_prepare_pt_sel_window((Nova::Utcb *)ep->utcb());
|
||||
srv << IPC_REPLY;
|
||||
@ -181,10 +190,10 @@ void Rpc_entrypoint::activate()
|
||||
* construction time. However, it executes no code because processing
|
||||
* time is always provided by the caller of the server activation. To
|
||||
* delay the processing of requests until the 'activate' function is
|
||||
* called, we grab the '_curr_obj_lock' on construction and release it
|
||||
* called, we grab the '_delay_start' lock on construction and release it
|
||||
* here.
|
||||
*/
|
||||
_curr_obj_lock.unlock();
|
||||
_delay_start.unlock();
|
||||
}
|
||||
|
||||
|
||||
@ -192,8 +201,8 @@ Rpc_entrypoint::Rpc_entrypoint(Cap_session *cap_session, size_t stack_size,
|
||||
const char *name, bool start_on_construction)
|
||||
:
|
||||
Thread_base(name, stack_size),
|
||||
_curr_obj(0),
|
||||
_curr_obj_lock(Lock::LOCKED),
|
||||
_curr_obj(start_on_construction ? 0 : (Rpc_object_base *)~0UL),
|
||||
_delay_start(Lock::LOCKED),
|
||||
_cap_session(cap_session)
|
||||
{
|
||||
/**
|
||||
|
@ -32,7 +32,7 @@ Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
|
||||
Rm_session::Local_addr local_addr,
|
||||
bool executable)
|
||||
{
|
||||
Dataspace_component *ds = static_cast<Dataspace_component *>(_ds_ep->obj_by_cap(ds_cap));
|
||||
Object_pool<Dataspace_component>::Guard ds(_ds_ep->lookup_and_lock(ds_cap));
|
||||
if (!ds)
|
||||
throw Invalid_dataspace();
|
||||
|
||||
|
@ -22,7 +22,8 @@ using namespace Genode;
|
||||
Native_capability
|
||||
Cpu_session_component::native_cap(Thread_capability thread_cap)
|
||||
{
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard
|
||||
thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread || !thread->platform_thread())
|
||||
return Native_capability::invalid_cap();
|
||||
|
||||
@ -30,9 +31,10 @@ Cpu_session_component::native_cap(Thread_capability thread_cap)
|
||||
}
|
||||
|
||||
Native_capability
|
||||
Cpu_session_component::pause_sync(Thread_capability target_thread_cap)
|
||||
Cpu_session_component::pause_sync(Thread_capability thread_cap)
|
||||
{
|
||||
Cpu_thread_component *thread = _lookup_thread(target_thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard
|
||||
thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread || !thread->platform_thread())
|
||||
return Native_capability::invalid_cap();
|
||||
|
||||
@ -44,7 +46,8 @@ Cpu_session_component::single_step(Thread_capability thread_cap, bool enable)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard
|
||||
thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread || !thread->platform_thread())
|
||||
return;
|
||||
|
||||
|
@ -109,16 +109,6 @@ namespace Genode {
|
||||
*/
|
||||
Signal_context_capability _default_exception_handler;
|
||||
|
||||
/**
|
||||
* Lookup thread in CPU session by its capability
|
||||
*
|
||||
* \retval NULL thread capability is invalid or
|
||||
* does not belong to the CPU session
|
||||
*/
|
||||
Cpu_thread_component *_lookup_thread(Thread_capability thread) {
|
||||
return dynamic_cast<Cpu_thread_component *>
|
||||
(_thread_ep->obj_by_cap(thread)); }
|
||||
|
||||
/**
|
||||
* Raw thread-killing functionality
|
||||
*
|
||||
|
@ -37,7 +37,8 @@ void Pager_activation_base::entry()
|
||||
reply_pending = false;
|
||||
|
||||
/* lookup referenced object */
|
||||
Pager_object *obj = _ep ? _ep->obj_by_id(pager.badge()) : 0;
|
||||
Object_pool<Pager_object>::Guard _obj(_ep ? _ep->lookup_and_lock(pager.badge()) : 0);
|
||||
Pager_object *obj = _obj;
|
||||
|
||||
/* handle request */
|
||||
if (obj) {
|
||||
@ -102,7 +103,7 @@ Pager_entrypoint::Pager_entrypoint(Cap_session *, Pager_activation_base *a)
|
||||
|
||||
void Pager_entrypoint::dissolve(Pager_object *obj)
|
||||
{
|
||||
remove(obj);
|
||||
remove_locked(obj);
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@ Core_rm_session::attach(Dataspace_capability ds_cap, size_t size,
|
||||
{
|
||||
using namespace Okl4;
|
||||
|
||||
Dataspace_component *ds = static_cast<Dataspace_component *>(_ds_ep->obj_by_cap(ds_cap));
|
||||
Object_pool<Dataspace_component>::Guard ds(_ds_ep->lookup_and_lock(ds_cap));
|
||||
if (!ds)
|
||||
throw Invalid_dataspace();
|
||||
|
||||
|
@ -21,8 +21,8 @@ using namespace Genode;
|
||||
|
||||
void Pd_session_component::space_pager(Thread_capability thread)
|
||||
{
|
||||
Cpu_thread_component *cpu_thread = dynamic_cast<Cpu_thread_component *>
|
||||
(_thread_ep->obj_by_cap(thread));
|
||||
Object_pool<Cpu_thread_component>::Guard
|
||||
cpu_thread(_thread_ep->lookup_and_lock(thread));
|
||||
if (!cpu_thread) return;
|
||||
_pd.space_pager(cpu_thread->platform_thread());
|
||||
}
|
||||
|
@ -33,19 +33,26 @@ void Pager_activation_base::entry()
|
||||
_cap = pager;
|
||||
_cap_valid.unlock();
|
||||
|
||||
pager.wait_for_fault();
|
||||
Pager_object * obj;
|
||||
bool reply = false;
|
||||
|
||||
while (1) {
|
||||
|
||||
if (reply)
|
||||
pager.reply_and_wait_for_fault();
|
||||
else
|
||||
pager.wait_for_fault();
|
||||
|
||||
/* lookup referenced object */
|
||||
Pager_object *obj = _ep ? _ep->obj_by_id(pager.badge()) : 0;
|
||||
Object_pool<Pager_object>::Guard _obj(_ep ? _ep->lookup_and_lock(pager.badge()) : 0);
|
||||
obj = _obj;
|
||||
reply = false;
|
||||
|
||||
/* handle request */
|
||||
if (obj) {
|
||||
if (obj->pager(pager))
|
||||
/* something strange occured - leave thread in pagefault */
|
||||
pager.wait_for_fault();
|
||||
else
|
||||
pager.reply_and_wait_for_fault();
|
||||
/* if something strange occurred - leave thread in pagefault */
|
||||
reply = !obj->pager(pager);
|
||||
continue;
|
||||
} else {
|
||||
|
||||
/* prevent threads outside of core to mess with our wake-up interface */
|
||||
@ -81,7 +88,6 @@ void Pager_activation_base::entry()
|
||||
pager.set_reply_dst(obj->cap());
|
||||
pager.acknowledge_wakeup();
|
||||
}
|
||||
pager.wait_for_fault();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -98,7 +104,7 @@ Pager_entrypoint::Pager_entrypoint(Cap_session *, Pager_activation_base *a)
|
||||
|
||||
void Pager_entrypoint::dissolve(Pager_object *obj)
|
||||
{
|
||||
remove(obj);
|
||||
remove_locked(obj);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Object pool - map ids to objects
|
||||
* \author Norman Feske
|
||||
* \author Alexander Boettcher
|
||||
* \date 2006-06-26
|
||||
*/
|
||||
|
||||
@ -33,17 +34,58 @@ namespace Genode {
|
||||
{
|
||||
public:
|
||||
|
||||
class Guard
|
||||
{
|
||||
private:
|
||||
|
||||
OBJ_TYPE * _object;
|
||||
|
||||
public:
|
||||
operator OBJ_TYPE*() const { return _object; }
|
||||
OBJ_TYPE * operator->() const { return _object; }
|
||||
OBJ_TYPE * object() const { return _object; }
|
||||
|
||||
template <class X>
|
||||
explicit Guard(X * object) {
|
||||
_object = dynamic_cast<OBJ_TYPE *>(object); }
|
||||
|
||||
~Guard()
|
||||
{
|
||||
if (!_object) return;
|
||||
|
||||
_object->release();
|
||||
}
|
||||
};
|
||||
|
||||
class Entry : public Avl_node<Entry>
|
||||
{
|
||||
private:
|
||||
|
||||
Untyped_capability _cap;
|
||||
short int _ref;
|
||||
bool _dead;
|
||||
|
||||
inline long _obj_id() { return _cap.local_name(); }
|
||||
Lock _entry_lock;
|
||||
|
||||
inline unsigned long _obj_id() { return _cap.local_name(); }
|
||||
|
||||
friend class Object_pool;
|
||||
friend class Avl_tree<Entry>;
|
||||
|
||||
/**
|
||||
* Support functions for atomic lookup and lock
|
||||
* functionality of class Object_pool.
|
||||
*/
|
||||
void lock() { _entry_lock.lock(); };
|
||||
void unlock() { _entry_lock.unlock(); };
|
||||
|
||||
void add_ref() { _ref += 1; }
|
||||
void del_ref() { _ref -= 1; }
|
||||
|
||||
bool is_dead(bool set_dead = false) {
|
||||
return (set_dead ? (_dead = true) : _dead); }
|
||||
bool is_ref_zero() { return _ref <= 0; }
|
||||
|
||||
public:
|
||||
|
||||
enum { OBJ_ID_INVALID = 0 };
|
||||
@ -51,8 +93,8 @@ namespace Genode {
|
||||
/**
|
||||
* Constructors
|
||||
*/
|
||||
Entry() { }
|
||||
Entry(Untyped_capability cap) : _cap(cap) { }
|
||||
Entry() : _ref(0), _dead(false) { }
|
||||
Entry(Untyped_capability cap) : _cap(cap), _ref(0), _dead(false) { }
|
||||
|
||||
/**
|
||||
* Avl_node interface
|
||||
@ -63,7 +105,7 @@ namespace Genode {
|
||||
/**
|
||||
* Support for object pool
|
||||
*/
|
||||
Entry *find_by_obj_id(long obj_id)
|
||||
Entry *find_by_obj_id(unsigned long obj_id)
|
||||
{
|
||||
if (obj_id == _obj_id()) return this;
|
||||
|
||||
@ -78,6 +120,12 @@ namespace Genode {
|
||||
void cap(Untyped_capability c) { _cap = c; }
|
||||
|
||||
Untyped_capability const cap() const { return _cap; }
|
||||
|
||||
/**
|
||||
* Function used - ideally - solely by the Guard.
|
||||
*/
|
||||
void release() { del_ref(); unlock(); }
|
||||
void acquire() { lock(); add_ref(); }
|
||||
};
|
||||
|
||||
private:
|
||||
@ -93,25 +141,49 @@ namespace Genode {
|
||||
_tree.insert(obj);
|
||||
}
|
||||
|
||||
void remove(OBJ_TYPE *obj)
|
||||
void remove_locked(OBJ_TYPE *obj)
|
||||
{
|
||||
Lock::Guard lock_guard(_lock);
|
||||
_tree.remove(obj);
|
||||
obj->is_dead(true);
|
||||
obj->del_ref();
|
||||
|
||||
while (true) {
|
||||
obj->unlock();
|
||||
{
|
||||
Lock::Guard lock_guard(_lock);
|
||||
if (obj->is_ref_zero()) {
|
||||
_tree.remove(obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
obj->lock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup object
|
||||
*/
|
||||
OBJ_TYPE *obj_by_id(long obj_id)
|
||||
OBJ_TYPE *lookup_and_lock(addr_t obj_id)
|
||||
{
|
||||
Lock::Guard lock_guard(_lock);
|
||||
Entry *obj = _tree.first();
|
||||
return (OBJ_TYPE *)(obj ? obj->find_by_obj_id(obj_id) : 0);
|
||||
OBJ_TYPE * obj_typed;
|
||||
{
|
||||
Lock::Guard lock_guard(_lock);
|
||||
Entry *obj = _tree.first();
|
||||
if (!obj) return 0;
|
||||
|
||||
obj_typed = (OBJ_TYPE *)obj->find_by_obj_id(obj_id);
|
||||
if (!obj_typed || obj_typed->is_dead())
|
||||
return 0;
|
||||
|
||||
obj_typed->add_ref();
|
||||
}
|
||||
|
||||
obj_typed->lock();
|
||||
return obj_typed;
|
||||
}
|
||||
|
||||
OBJ_TYPE *obj_by_cap(Untyped_capability cap)
|
||||
OBJ_TYPE *lookup_and_lock(Untyped_capability cap)
|
||||
{
|
||||
return obj_by_id(cap.local_name());
|
||||
return lookup_and_lock(cap.local_name());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -180,26 +180,10 @@ namespace Genode {
|
||||
|
||||
class Rpc_object_base : public Object_pool<Rpc_object_base>::Entry
|
||||
{
|
||||
private:
|
||||
|
||||
Lock _dispatch_lock;
|
||||
|
||||
public:
|
||||
|
||||
virtual ~Rpc_object_base() { }
|
||||
|
||||
/*
|
||||
* Serialize access with dispatch loop
|
||||
*
|
||||
* These methods are used for the destruction of server objects.
|
||||
* They are exclusively used by 'Server_activation_base::entry()'
|
||||
* and 'Rpc_entrypoint::dissolve()'. Never use this lock for other
|
||||
* purposes.
|
||||
*/
|
||||
|
||||
void lock() { _dispatch_lock.lock(); }
|
||||
void unlock() { _dispatch_lock.unlock(); }
|
||||
|
||||
/**
|
||||
* Interface to be implemented by a derived class
|
||||
*
|
||||
|
@ -223,9 +223,8 @@ namespace Genode {
|
||||
{
|
||||
if (!args.is_valid_string()) throw Root::Invalid_args();
|
||||
|
||||
SESSION_TYPE *s =
|
||||
dynamic_cast<SESSION_TYPE *>(_ep->obj_by_cap(session));
|
||||
|
||||
typedef typename Object_pool<SESSION_TYPE>::Guard Object_guard;
|
||||
Object_guard s(_ep->lookup_and_lock(session));
|
||||
if (!s) return;
|
||||
|
||||
_upgrade_session(s, args.string());
|
||||
@ -233,9 +232,8 @@ namespace Genode {
|
||||
|
||||
void close(Session_capability session)
|
||||
{
|
||||
SESSION_TYPE *s =
|
||||
dynamic_cast<SESSION_TYPE *>(_ep->obj_by_cap(session));
|
||||
|
||||
SESSION_TYPE * s =
|
||||
dynamic_cast<SESSION_TYPE *>(_ep->lookup_and_lock(session));
|
||||
if (!s) return;
|
||||
|
||||
/* let the entry point forget the session object */
|
||||
|
@ -198,7 +198,7 @@ void Child::_add_session(Child::Session const &s)
|
||||
void Child::_remove_session(Child::Session *s)
|
||||
{
|
||||
/* forget about this session */
|
||||
_session_pool.remove(s);
|
||||
_session_pool.remove_locked(s);
|
||||
_session_list.remove(s);
|
||||
|
||||
/* return session quota to the ram session of the child */
|
||||
@ -303,7 +303,7 @@ void Child::upgrade(Session_capability to_session, Parent::Upgrade_args const &a
|
||||
targeted_service = &_rm_service;
|
||||
|
||||
/* check if upgrade refers to server */
|
||||
Session * const session = _session_pool.obj_by_cap(to_session);
|
||||
Object_pool<Session>::Guard session(_session_pool.lookup_and_lock(to_session));
|
||||
if (session)
|
||||
targeted_service = session->service();
|
||||
|
||||
@ -350,7 +350,7 @@ void Child::close(Session_capability session_cap)
|
||||
|| session_cap.local_name() == _process.pd_session_cap().local_name())
|
||||
return;
|
||||
|
||||
Session *s = _session_pool.obj_by_cap(session_cap);
|
||||
Session *s = _session_pool.lookup_and_lock(session_cap);
|
||||
|
||||
if (!s) {
|
||||
PWRN("no session structure found");
|
||||
|
@ -21,7 +21,7 @@ using namespace Genode;
|
||||
void Rpc_entrypoint::_dissolve(Rpc_object_base *obj)
|
||||
{
|
||||
/* make sure nobody is able to find this object */
|
||||
remove(obj);
|
||||
remove_locked(obj);
|
||||
|
||||
/*
|
||||
* The activation may execute a blocking operation in a dispatch function.
|
||||
@ -32,7 +32,7 @@ void Rpc_entrypoint::_dissolve(Rpc_object_base *obj)
|
||||
_leave_server_object(obj);
|
||||
|
||||
/* wait until nobody is inside dispatch */
|
||||
obj->lock();
|
||||
obj->acquire();
|
||||
|
||||
_cap_session->free(obj->cap());
|
||||
|
||||
|
@ -66,22 +66,23 @@ void Rpc_entrypoint::entry()
|
||||
srv.ret(ERR_INVALID_OBJECT);
|
||||
|
||||
/* atomically lookup and lock referenced object */
|
||||
Object_pool<Rpc_object_base>::Guard curr_obj(lookup_and_lock(srv.badge()));
|
||||
if (!curr_obj)
|
||||
continue;
|
||||
|
||||
{
|
||||
Lock::Guard lock_guard(_curr_obj_lock);
|
||||
|
||||
_curr_obj = obj_by_id(srv.badge());
|
||||
if (!_curr_obj)
|
||||
continue;
|
||||
|
||||
_curr_obj->lock();
|
||||
_curr_obj = curr_obj;
|
||||
}
|
||||
|
||||
/* dispatch request */
|
||||
try { srv.ret(_curr_obj->dispatch(opcode, srv, srv)); }
|
||||
catch (Blocking_canceled) { }
|
||||
|
||||
_curr_obj->unlock();
|
||||
_curr_obj = 0;
|
||||
{
|
||||
Lock::Guard lock_guard(_curr_obj_lock);
|
||||
_curr_obj = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* answer exit call, thereby wake up '~Rpc_entrypoint' */
|
||||
|
@ -72,7 +72,8 @@ void Cpu_session_component::kill_thread(Thread_capability thread_cap)
|
||||
{
|
||||
Lock::Guard lock_guard(_thread_list_lock);
|
||||
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Cpu_thread_component * thread =
|
||||
dynamic_cast<Cpu_thread_component *>(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return;
|
||||
|
||||
_unsynchronized_kill_thread(thread);
|
||||
@ -82,10 +83,10 @@ void Cpu_session_component::kill_thread(Thread_capability thread_cap)
|
||||
int Cpu_session_component::set_pager(Thread_capability thread_cap,
|
||||
Pager_capability pager_cap)
|
||||
{
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return -1;
|
||||
|
||||
Pager_object *p = dynamic_cast<Pager_object *>(_pager_ep->obj_by_cap(pager_cap));
|
||||
Object_pool<Pager_object>::Guard p(_pager_ep->lookup_and_lock(pager_cap));
|
||||
if (!p) return -2;
|
||||
|
||||
thread->platform_thread()->pager(p);
|
||||
@ -99,7 +100,7 @@ int Cpu_session_component::set_pager(Thread_capability thread_cap,
|
||||
int Cpu_session_component::start(Thread_capability thread_cap,
|
||||
addr_t ip, addr_t sp)
|
||||
{
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return -1;
|
||||
|
||||
/*
|
||||
@ -114,7 +115,7 @@ int Cpu_session_component::start(Thread_capability thread_cap,
|
||||
|
||||
void Cpu_session_component::pause(Thread_capability thread_cap)
|
||||
{
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return;
|
||||
|
||||
thread->platform_thread()->pause();
|
||||
@ -123,7 +124,7 @@ void Cpu_session_component::pause(Thread_capability thread_cap)
|
||||
|
||||
void Cpu_session_component::resume(Thread_capability thread_cap)
|
||||
{
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return;
|
||||
|
||||
thread->platform_thread()->resume();
|
||||
@ -132,27 +133,28 @@ void Cpu_session_component::resume(Thread_capability thread_cap)
|
||||
|
||||
void Cpu_session_component::cancel_blocking(Thread_capability thread_cap)
|
||||
{
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return;
|
||||
|
||||
if (thread)
|
||||
thread->platform_thread()->cancel_blocking();
|
||||
thread->platform_thread()->cancel_blocking();
|
||||
}
|
||||
|
||||
|
||||
Thread_state Cpu_session_component::state(Thread_capability thread_cap)
|
||||
{
|
||||
Cpu_thread_component * thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) throw State_access_failed();
|
||||
Thread_state state = thread->platform_thread()->state();
|
||||
return state;
|
||||
|
||||
return thread->platform_thread()->state();
|
||||
}
|
||||
|
||||
|
||||
void Cpu_session_component::state(Thread_capability thread_cap,
|
||||
Thread_state const &state)
|
||||
{
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) throw State_access_failed();
|
||||
|
||||
thread->platform_thread()->state(state);
|
||||
}
|
||||
|
||||
@ -178,7 +180,7 @@ Cpu_session_component::exception_handler(Thread_capability thread_cap,
|
||||
sigh_cap = _default_exception_handler;
|
||||
}
|
||||
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return;
|
||||
|
||||
thread->sigh(sigh_cap);
|
||||
@ -193,7 +195,7 @@ unsigned Cpu_session_component::num_cpus() const
|
||||
|
||||
void Cpu_session_component::affinity(Thread_capability thread_cap, unsigned cpu)
|
||||
{
|
||||
Cpu_thread_component *thread = _lookup_thread(thread_cap);
|
||||
Object_pool<Cpu_thread_component>::Guard thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return;
|
||||
|
||||
thread->platform_thread()->affinity(cpu);
|
||||
|
@ -41,7 +41,8 @@ namespace Genode {
|
||||
Local_addr local_addr = 0,
|
||||
bool executable = false)
|
||||
{
|
||||
Dataspace_component *ds = static_cast<Dataspace_component *>(_ds_ep->obj_by_cap(ds_cap));
|
||||
Object_pool<Dataspace_component>::Guard
|
||||
ds(_ds_ep->lookup_and_lock(ds_cap));
|
||||
if (!ds)
|
||||
throw Invalid_dataspace();
|
||||
|
||||
|
@ -103,16 +103,6 @@ namespace Genode {
|
||||
*/
|
||||
Signal_context_capability _default_exception_handler;
|
||||
|
||||
/**
|
||||
* Lookup thread in CPU session by its capability
|
||||
*
|
||||
* \retval NULL thread capability is invalid or
|
||||
* does not belong to the CPU session
|
||||
*/
|
||||
Cpu_thread_component *_lookup_thread(Thread_capability thread) {
|
||||
return dynamic_cast<Cpu_thread_component *>
|
||||
(_thread_ep->obj_by_cap(thread)); }
|
||||
|
||||
/**
|
||||
* Raw thread-killing functionality
|
||||
*
|
||||
|
@ -26,8 +26,7 @@ using namespace Genode;
|
||||
|
||||
int Pd_session_component::bind_thread(Thread_capability thread)
|
||||
{
|
||||
Cpu_thread_component *cpu_thread = dynamic_cast<Cpu_thread_component *>
|
||||
(_thread_ep->obj_by_cap(thread));
|
||||
Object_pool<Cpu_thread_component>::Guard cpu_thread(_thread_ep->lookup_and_lock(thread));
|
||||
if (!cpu_thread) return -1;
|
||||
|
||||
if (cpu_thread->bound()) {
|
||||
|
@ -26,9 +26,7 @@ static const bool verbose = false;
|
||||
|
||||
addr_t Ram_session_component::phys_addr(Ram_dataspace_capability ds)
|
||||
{
|
||||
Dataspace_component * const dsc =
|
||||
dynamic_cast<Dataspace_component *>(_ds_ep->obj_by_cap(ds));
|
||||
|
||||
Object_pool<Dataspace_component>::Guard dsc(_ds_ep->lookup_and_lock(ds));
|
||||
if (!dsc) throw Invalid_dataspace();
|
||||
return dsc->phys_addr();
|
||||
}
|
||||
@ -201,7 +199,12 @@ Ram_dataspace_capability Ram_session_component::alloc(size_t ds_size, bool cache
|
||||
|
||||
void Ram_session_component::free(Ram_dataspace_capability ds_cap)
|
||||
{
|
||||
_free_ds(dynamic_cast<Dataspace_component *>(_ds_ep->obj_by_cap(ds_cap)));
|
||||
Dataspace_component * ds =
|
||||
dynamic_cast<Dataspace_component *>(_ds_ep->lookup_and_lock(ds_cap));
|
||||
if (!ds)
|
||||
return;
|
||||
|
||||
_free_ds(ds);
|
||||
}
|
||||
|
||||
|
||||
@ -210,8 +213,7 @@ int Ram_session_component::ref_account(Ram_session_capability ram_session_cap)
|
||||
/* the reference account cannot be defined twice */
|
||||
if (_ref_account) return -2;
|
||||
|
||||
Ram_session_component *ref = dynamic_cast<Ram_session_component *>
|
||||
(_ram_session_ep->obj_by_cap(ram_session_cap));
|
||||
Object_pool<Ram_session_component>::Guard ref(_ram_session_ep->lookup_and_lock(ram_session_cap));
|
||||
|
||||
/* check if recipient is a valid Ram_session_component */
|
||||
if (!ref) return -1;
|
||||
@ -231,9 +233,8 @@ int Ram_session_component::transfer_quota(Ram_session_capability ram_session_cap
|
||||
{
|
||||
if (verbose)
|
||||
PDBG("amount=%zd", amount);
|
||||
Ram_session_component *dst = dynamic_cast<Ram_session_component *>
|
||||
(_ram_session_ep->obj_by_cap(ram_session_cap));
|
||||
|
||||
Object_pool<Ram_session_component>::Guard dst(_ram_session_ep->lookup_and_lock(ram_session_cap));
|
||||
return _transfer_quota(dst, amount);
|
||||
}
|
||||
|
||||
|
@ -331,8 +331,7 @@ Rm_session_component::attach(Dataspace_capability ds_cap, size_t size,
|
||||
throw Invalid_args();
|
||||
|
||||
/* check dataspace validity */
|
||||
Dataspace_component *dsc = dynamic_cast<Dataspace_component *>
|
||||
(_ds_ep->obj_by_cap(ds_cap));
|
||||
Object_pool<Dataspace_component>::Guard dsc(_ds_ep->lookup_and_lock(ds_cap));
|
||||
if (!dsc) throw Invalid_dataspace();
|
||||
|
||||
if (!size) {
|
||||
@ -417,7 +416,7 @@ Rm_session_component::attach(Dataspace_capability ds_cap, size_t size,
|
||||
|
||||
if (verbose)
|
||||
PDBG("attach ds %p (a=%lx,s=%zx,o=%lx) @ [%lx,%lx)",
|
||||
dsc, dsc->phys_addr(), dsc->size(), offset, (addr_t)r, (addr_t)r + size);
|
||||
(Dataspace_component *)dsc, dsc->phys_addr(), dsc->size(), offset, (addr_t)r, (addr_t)r + size);
|
||||
|
||||
/* check if attach operation resolves any faulting region-manager clients */
|
||||
for (Rm_faulter *faulter = _faulters.head(); faulter; ) {
|
||||
@ -563,17 +562,21 @@ void Rm_session_component::detach(Local_addr local_addr)
|
||||
|
||||
Pager_capability Rm_session_component::add_client(Thread_capability thread)
|
||||
{
|
||||
unsigned long badge;
|
||||
|
||||
{
|
||||
/* lookup thread and setup correct parameters */
|
||||
Object_pool<Cpu_thread_component>::Guard
|
||||
cpu_thread(_thread_ep->lookup_and_lock(thread));
|
||||
if (!cpu_thread) throw Invalid_thread();
|
||||
|
||||
/* determine identification of client when faulting */
|
||||
badge = cpu_thread->platform_thread()->pager_object_badge();
|
||||
}
|
||||
|
||||
/* serialize access */
|
||||
Lock::Guard lock_guard(_lock);
|
||||
|
||||
/* lookup thread and setup correct parameters */
|
||||
Cpu_thread_component *cpu_thread = dynamic_cast<Cpu_thread_component *>
|
||||
(_thread_ep->obj_by_cap(thread));
|
||||
if (!cpu_thread) throw Invalid_thread();
|
||||
|
||||
/* determine identification of client when faulting */
|
||||
unsigned long badge = cpu_thread->platform_thread()->pager_object_badge();
|
||||
|
||||
Rm_client *cl;
|
||||
try { cl = new(&_client_slab) Rm_client(this, badge); }
|
||||
catch (Allocator::Out_of_memory) { throw Out_of_metadata(); }
|
||||
@ -758,18 +761,24 @@ Rm_session_component::~Rm_session_component()
|
||||
|
||||
/* remove all clients */
|
||||
while (Rm_client *cl = _client_slab.raw()->first_object()) {
|
||||
Thread_capability thread_cap = cl->thread_cap();
|
||||
if (thread_cap.valid()) {
|
||||
/* lookup thread and reset pager pointer */
|
||||
Cpu_thread_component *cpu_thread = dynamic_cast<Cpu_thread_component *>
|
||||
(_thread_ep->obj_by_cap(thread_cap));
|
||||
if (cpu_thread)
|
||||
cpu_thread->platform_thread()->pager(0);
|
||||
}
|
||||
Thread_capability thread_cap = cl->thread_cap();
|
||||
if (thread_cap.valid())
|
||||
/* invalidate thread cap in rm_client object */
|
||||
cl->thread_cap(Thread_capability());
|
||||
|
||||
_lock.unlock();
|
||||
|
||||
cl->dissolve_from_faulting_rm_session();
|
||||
this->dissolve(cl);
|
||||
|
||||
{
|
||||
/* lookup thread and reset pager pointer */
|
||||
Object_pool<Cpu_thread_component>::Guard
|
||||
cpu_thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (cpu_thread)
|
||||
cpu_thread->platform_thread()->pager(0);
|
||||
}
|
||||
|
||||
_lock.lock();
|
||||
}
|
||||
|
||||
|
@ -71,10 +71,8 @@ Signal_context_capability Signal_session_component::alloc_context(long imprint)
|
||||
|
||||
void Signal_session_component::free_context(Signal_context_capability context_cap)
|
||||
{
|
||||
Signal_context_component *context;
|
||||
context = dynamic_cast<Signal_context_component *>
|
||||
(_context_ep->obj_by_cap(context_cap));
|
||||
|
||||
Signal_context_component * context =
|
||||
dynamic_cast<Signal_context_component *>(_context_ep->lookup_and_lock(context_cap));
|
||||
if (!context) {
|
||||
PWRN("specified signal-context capability has wrong type");
|
||||
return;
|
||||
@ -88,10 +86,8 @@ void Signal_session_component::free_context(Signal_context_capability context_ca
|
||||
void Signal_session_component::submit(Signal_context_capability context_cap,
|
||||
unsigned cnt)
|
||||
{
|
||||
Signal_context_component *context;
|
||||
context = dynamic_cast<Signal_context_component *>
|
||||
(_context_ep->obj_by_cap(context_cap));
|
||||
|
||||
Object_pool<Signal_context_component>::Guard
|
||||
context(_context_ep->lookup_and_lock(context_cap));
|
||||
if (!context) {
|
||||
/*
|
||||
* We do not use PWRN() to enable the build system to suppress this
|
||||
|
@ -156,8 +156,8 @@ namespace Pci {
|
||||
Config_access config_access;
|
||||
|
||||
/* lookup device component for previous device */
|
||||
Device_component *prev = dynamic_cast<Device_component *>
|
||||
(_ep->obj_by_cap(prev_device));
|
||||
Genode::Object_pool<Device_component>::Guard
|
||||
prev(_ep->lookup_and_lock(prev_device));
|
||||
|
||||
/*
|
||||
* Start bus scanning after the previous device's location.
|
||||
@ -200,7 +200,7 @@ namespace Pci {
|
||||
{
|
||||
/* lookup device component for previous device */
|
||||
Device_component *device = dynamic_cast<Device_component *>
|
||||
(_ep->obj_by_cap(device_cap));
|
||||
(_ep->lookup_and_lock(device_cap));
|
||||
|
||||
if (!device)
|
||||
return;
|
||||
|
@ -98,7 +98,9 @@ namespace Timer {
|
||||
*/
|
||||
bool belongs_to(Genode::Session_capability cap)
|
||||
{
|
||||
return _entrypoint.obj_by_cap(cap) == this;
|
||||
Genode::Object_pool<Session_component>::Guard
|
||||
lcap(_entrypoint.lookup_and_lock(cap));
|
||||
return lcap == this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,7 +165,9 @@ namespace Timer {
|
||||
*/
|
||||
bool belongs_to(Genode::Session_capability cap)
|
||||
{
|
||||
return _entrypoint.obj_by_cap(cap) == this;
|
||||
Genode::Object_pool<Session_component>::Guard
|
||||
lcap(_entrypoint.lookup_and_lock(cap));
|
||||
return lcap == this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,7 +104,7 @@ namespace Loader {
|
||||
{
|
||||
Lock::Guard guard(_lock);
|
||||
|
||||
Rpc_object_base *rom = _ep.obj_by_cap(session);
|
||||
Rpc_object_base *rom = _ep.lookup_and_lock(session);
|
||||
|
||||
Rom_session_component *component =
|
||||
dynamic_cast<Rom_session_component *>(rom);
|
||||
|
@ -235,8 +235,8 @@ namespace Audio_out {
|
||||
|
||||
void sync_session(Session_capability audio_out_session)
|
||||
{
|
||||
Session_component *sc = dynamic_cast<Session_component *>
|
||||
(audio_out_ep()->obj_by_cap(audio_out_session));
|
||||
Object_pool<Session_component>::Guard
|
||||
sc(audio_out_ep()->lookup_and_lock(audio_out_session));
|
||||
|
||||
/* check if recipient is a valid session component */
|
||||
if (!sc) return;
|
||||
|
@ -411,8 +411,7 @@ class View_component : public Genode::List<View_component>::Element,
|
||||
|
||||
int stack(Nitpicker::View_capability neighbor_cap, bool behind, bool redraw)
|
||||
{
|
||||
View_component *nvc;
|
||||
nvc = dynamic_cast<View_component *>(_ep->obj_by_cap(neighbor_cap));
|
||||
Genode::Object_pool<View_component>::Guard nvc(_ep->lookup_and_lock(neighbor_cap));
|
||||
|
||||
::View *neighbor_view = nvc ? nvc->view() : 0;
|
||||
|
||||
@ -546,7 +545,7 @@ namespace Nitpicker {
|
||||
|
||||
void destroy_view(View_capability view_cap)
|
||||
{
|
||||
View_component *vc = dynamic_cast<View_component *>(_ep->obj_by_cap(view_cap));
|
||||
View_component *vc = dynamic_cast<View_component *>(_ep->lookup_and_lock(view_cap));
|
||||
if (!vc) return;
|
||||
|
||||
_view_stack->remove_view(vc->view());
|
||||
@ -558,7 +557,7 @@ namespace Nitpicker {
|
||||
int background(View_capability view_cap)
|
||||
{
|
||||
if (_provides_default_bg) {
|
||||
View_component *vc = dynamic_cast<View_component *>(_ep->obj_by_cap(view_cap));
|
||||
Genode::Object_pool<View_component>::Guard vc(_ep->lookup_and_lock(view_cap));
|
||||
vc->view()->background(true);
|
||||
_view_stack->default_background(vc->view());
|
||||
return 0;
|
||||
@ -568,7 +567,7 @@ namespace Nitpicker {
|
||||
if (::Session::background()) ::Session::background()->background(false);
|
||||
|
||||
/* assign session background */
|
||||
View_component *vc = dynamic_cast<View_component *>(_ep->obj_by_cap(view_cap));
|
||||
Genode::Object_pool<View_component>::Guard vc(_ep->lookup_and_lock(view_cap));
|
||||
::Session::background(vc->view());
|
||||
|
||||
/* switch background view to background mode */
|
||||
|
@ -44,7 +44,8 @@ Genode::Session_capability Session_component::cap()
|
||||
|
||||
bool Session_component::belongs_to(Genode::Session_capability cap)
|
||||
{
|
||||
return _ep.obj_by_cap(cap) == this;
|
||||
Object_pool<Session_component>::Guard session(_ep.lookup_and_lock(cap));
|
||||
return session == this;
|
||||
}
|
||||
|
||||
|
||||
|
@ -203,13 +203,13 @@ namespace Gdb_monitor {
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
Child_session *session = _sessions.obj_by_cap(session_cap);
|
||||
Child_session *session = _sessions.lookup_and_lock(session_cap);
|
||||
if (!session) {
|
||||
PERR("attempt to close unknown session");
|
||||
return;
|
||||
}
|
||||
Genode::size_t ram_quota = session->ram_quota;
|
||||
_sessions.remove(session);
|
||||
_sessions.remove_locked(session);
|
||||
destroy(env()->heap(), session);
|
||||
|
||||
_child_root.close(session_cap);
|
||||
|
@ -42,7 +42,7 @@ Rm_session_component::Region *Rm_session_component::find_region(void *local_addr
|
||||
*offset_in_region = ((addr_t)local_addr - (addr_t)region->start());
|
||||
// PDBG("offset_in_region = %lx", *offset_in_region);
|
||||
|
||||
Dataspace_object *managed_ds_obj = _managed_ds_map->obj_by_cap(region->ds_cap());
|
||||
Object_pool<Dataspace_object>::Guard managed_ds_obj(_managed_ds_map->lookup_and_lock(region->ds_cap()));
|
||||
if (managed_ds_obj) {
|
||||
// PDBG("managed dataspace detected");
|
||||
region = managed_ds_obj->rm_session_component()->find_region((void*)*offset_in_region, offset_in_region);
|
||||
|
@ -92,7 +92,7 @@ namespace Noux {
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
_pool.remove(info);
|
||||
_pool.remove_locked(info);
|
||||
destroy(env()->heap(), info);
|
||||
}
|
||||
}
|
||||
@ -104,12 +104,12 @@ namespace Noux {
|
||||
|
||||
void remove(Dataspace_info *info)
|
||||
{
|
||||
_pool.remove(info);
|
||||
_pool.remove_locked(info);
|
||||
}
|
||||
|
||||
Dataspace_info *lookup_info(Dataspace_capability ds_cap)
|
||||
{
|
||||
return _pool.obj_by_cap(ds_cap);
|
||||
return _pool.lookup_and_lock(ds_cap);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -120,9 +120,8 @@ namespace Noux {
|
||||
|
||||
void close(Genode::Session_capability session)
|
||||
{
|
||||
Rm_session_component *rm_session =
|
||||
dynamic_cast<Rm_session_component *>(_ep.obj_by_cap(session));
|
||||
|
||||
Object_pool<Rm_session_component>::Guard
|
||||
rm_session(_ep.lookup_and_lock(session));
|
||||
if (!rm_session) {
|
||||
PWRN("Unexpected call of close with non-RM-session argument");
|
||||
return;
|
||||
|
@ -107,7 +107,7 @@ namespace Noux {
|
||||
|
||||
Dataspace_capability ds;
|
||||
|
||||
Dataspace_info *info = _ds_registry.lookup_info(curr->ds);
|
||||
Object_pool<Dataspace_info>::Guard info(_ds_registry.lookup_info(curr->ds));
|
||||
|
||||
if (info) {
|
||||
|
||||
@ -163,7 +163,7 @@ namespace Noux {
|
||||
return;
|
||||
}
|
||||
|
||||
Dataspace_info *info = _ds_registry.lookup_info(region->ds);
|
||||
Object_pool<Dataspace_info>::Guard info(_ds_registry.lookup_info(region->ds));
|
||||
if (!info) {
|
||||
PERR("attempt to write to unknown dataspace type");
|
||||
for (;;);
|
||||
|
Loading…
x
Reference in New Issue
Block a user