diff --git a/base-codezero/src/base/pager/pager.cc b/base-codezero/src/base/pager/pager.cc index dbb14d03b..03c04c0b5 100644 --- a/base-codezero/src/base/pager/pager.cc +++ b/base-codezero/src/base/pager/pager.cc @@ -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::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.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.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); } diff --git a/base-codezero/src/core/core_rm_session.cc b/base-codezero/src/core/core_rm_session.cc index fbb08fad1..992919e10 100644 --- a/base-codezero/src/core/core_rm_session.cc +++ b/base-codezero/src/core/core_rm_session.cc @@ -30,7 +30,7 @@ Core_rm_session::attach(Dataspace_capability ds_cap, size_t size, { using namespace Codezero; - Dataspace_component *ds = static_cast(_ds_ep->obj_by_cap(ds_cap)); + Object_pool::Guard ds(_ds_ep->lookup_and_lock(ds_cap)); if (!ds) throw Invalid_dataspace(); diff --git a/base-fiasco/src/base/pager/pager.cc b/base-fiasco/src/base/pager/pager.cc index 9caefffa8..ea813e739 100644 --- a/base-fiasco/src/base/pager/pager.cc +++ b/base-fiasco/src/base/pager/pager.cc @@ -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::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); } diff --git a/base-foc/src/base/pager/pager.cc b/base-foc/src/base/pager/pager.cc index 2473efeab..2847bac7a 100644 --- a/base-foc/src/base/pager/pager.cc +++ b/base-foc/src/base/pager/pager.cc @@ -56,7 +56,7 @@ void Pager_activation_base::entry() } /* lookup referenced object */ - Pager_object *obj = _ep->obj_by_id(pager.badge()); + Object_pool::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::Entry::cap()); - remove(obj); + remove_locked(obj); } diff --git a/base-foc/src/base/server/server.cc b/base-foc/src/base/server/server.cc index 7a75da098..e28815815 100644 --- a/base-foc/src/base/server/server.cc +++ b/base-foc/src/base/server/server.cc @@ -71,22 +71,23 @@ void Rpc_entrypoint::entry() } /* atomically lookup and lock referenced object */ + Object_pool::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' */ diff --git a/base-foc/src/core/cpu_session_extension.cc b/base-foc/src/core/cpu_session_extension.cc index c73425449..f110a378d 100644 --- a/base-foc/src/core/cpu_session_extension.cc +++ b/base-foc/src/core/cpu_session_extension.cc @@ -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::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::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::Guard thread(_thread_ep->lookup_and_lock(thread_cap)); if (!thread) return; Native_thread tid = thread->platform_thread()->thread().local.dst(); diff --git a/base-foc/src/core/include/cpu_session_component.h b/base-foc/src/core/include/cpu_session_component.h index a1dfbf5c0..c54b6186f 100644 --- a/base-foc/src/core/include/cpu_session_component.h +++ b/base-foc/src/core/include/cpu_session_component.h @@ -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 - (_thread_ep->obj_by_cap(thread)); } - /** * Raw thread-killing functionality * diff --git a/base-hw/src/base/pager.cc b/base-hw/src/base/pager.cc index 53286c9f6..3a2adc980 100644 --- a/base-hw/src/base/pager.cc +++ b/base-hw/src/base/pager.cc @@ -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::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) diff --git a/base-hw/src/core/cpu_session_support.cc b/base-hw/src/core/cpu_session_support.cc index 253589564..59fb1ff3f 100644 --- a/base-hw/src/core/cpu_session_support.cc +++ b/base-hw/src/core/cpu_session_support.cc @@ -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::Guard + t(_thread_ep->lookup_and_lock(thread_cap)); if (!t) return Ram_dataspace_capability(); return t->platform_thread()->utcb(); } diff --git a/base-linux/include/base/pager.h b/base-linux/include/base/pager.h index 8d7605fed..596688e85 100644 --- a/base-linux/include/base/pager.h +++ b/base-linux/include/base/pager.h @@ -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 class Pager_activation : public Pager_activation_base { }; } diff --git a/base-linux/src/core/cpu_session_extension.cc b/base-linux/src/core/cpu_session_extension.cc index ad4b22486..d8b52a1de 100644 --- a/base-linux/src/core/cpu_session_extension.cc +++ b/base-linux/src/core/cpu_session_extension.cc @@ -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::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::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::Guard + thread(_thread_ep->lookup_and_lock(thread_cap)); if (!thread) return Untyped_capability(); enum { DUMMY_LOCAL_NAME = 0 }; diff --git a/base-linux/src/core/include/core_env.h b/base-linux/src/core/include/core_env.h index 5185aa294..13b5e703b 100644 --- a/base-linux/src/core/include/core_env.h +++ b/base-linux/src/core/include/core_env.h @@ -126,13 +126,6 @@ namespace Genode { { enum { STACK_SIZE = 2048 * sizeof(Genode::addr_t) }; - template - T *lookup(Capability cap) - { - Rpc_object_base *obj = obj_by_cap(cap); - return obj ? dynamic_cast(obj) : 0; - } - Entrypoint(Cap_session *cap_session) : Rpc_entrypoint(cap_session, STACK_SIZE, "entrypoint") diff --git a/base-linux/src/core/include/cpu_session_component.h b/base-linux/src/core/include/cpu_session_component.h index a682452d4..5da7c603f 100644 --- a/base-linux/src/core/include/cpu_session_component.h +++ b/base-linux/src/core/include/cpu_session_component.h @@ -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 - (_thread_ep->obj_by_cap(thread)); } - /** * Raw thread-killing functionality * diff --git a/base-linux/src/core/pd_session_component.cc b/base-linux/src/core/pd_session_component.cc index 9c565a4ee..d9a76625e 100644 --- a/base-linux/src/core/pd_session_component.cc +++ b/base-linux/src/core/pd_session_component.cc @@ -365,8 +365,7 @@ int Pd_session_component::assign_parent(Parent_capability parent) void Pd_session_component::start(Capability binary) { /* lookup binary dataspace */ - Dataspace_component *ds = - reinterpret_cast(_ds_ep->obj_by_cap(binary)); + Object_pool::Guard ds(_ds_ep->lookup_and_lock(binary)); if (!ds) { PERR("could not lookup binary, aborted PD startup"); diff --git a/base-linux/src/core/platform.cc b/base-linux/src/core/platform.cc index c3cfe7acf..8c0052fad 100644 --- a/base-linux/src/core/platform.cc +++ b/base-linux/src/core/platform.cc @@ -161,7 +161,9 @@ Platform_env_base::Rm_session_mmap::_dataspace_size(Capability ds_cap } /* use local function call if called from the entrypoint */ - Dataspace *ds = core_env()->entrypoint()->lookup(ds_cap); + Object_pool::Guard + ds_rpc(core_env()->entrypoint()->lookup_and_lock(ds_cap)); + Dataspace * ds = dynamic_cast(&*ds_rpc); return ds ? ds->size() : 0; } @@ -178,7 +180,9 @@ int Platform_env_base::Rm_session_mmap::_dataspace_fd(Capability ds_c Capability lx_ds_cap = static_cap_cast(ds_cap); - Linux_dataspace *ds = core_env()->entrypoint()->lookup(lx_ds_cap); + Object_pool::Guard + ds_rpc(core_env()->entrypoint()->lookup_and_lock(lx_ds_cap)); + Linux_dataspace * ds = dynamic_cast(&*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::Guard + ds_rpc(core_env()->entrypoint()->lookup_and_lock(ds_cap)); + Dataspace * ds = dynamic_cast(&*ds_rpc); return ds ? ds->writable() : false; } diff --git a/base-mb/src/base/pager/pager.cc b/base-mb/src/base/pager/pager.cc index 0880b7b7c..c57363e65 100644 --- a/base-mb/src/base/pager/pager.cc +++ b/base-mb/src/base/pager/pager.cc @@ -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::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) diff --git a/base-mb/src/core/core_rm_session.cc b/base-mb/src/core/core_rm_session.cc index 75506d092..1f842f56f 100644 --- a/base-mb/src/core/core_rm_session.cc +++ b/base-mb/src/core/core_rm_session.cc @@ -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(_ds_ep->obj_by_cap(ds_cap)); + Object_pool::Guard ds(_ds_ep->lookup_and_lock(ds_cap)); if (!ds) throw Invalid_dataspace(); diff --git a/base-nova/src/base/pager/pager.cc b/base-nova/src/base/pager/pager.cc index a6726ca64..efbc1fea8 100644 --- a/base-nova/src/base/pager/pager.cc +++ b/base-nova/src/base/pager/pager.cc @@ -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); } diff --git a/base-nova/src/base/server/server.cc b/base-nova/src/base/server/server.cc index 85c3b9377..c23b6e47a 100644 --- a/base-nova/src/base/server/server.cc +++ b/base-nova/src/base/server/server.cc @@ -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(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(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) { /** diff --git a/base-nova/src/core/core_rm_session.cc b/base-nova/src/core/core_rm_session.cc index 47d4e8675..c3ae5ee10 100644 --- a/base-nova/src/core/core_rm_session.cc +++ b/base-nova/src/core/core_rm_session.cc @@ -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(_ds_ep->obj_by_cap(ds_cap)); + Object_pool::Guard ds(_ds_ep->lookup_and_lock(ds_cap)); if (!ds) throw Invalid_dataspace(); diff --git a/base-nova/src/core/cpu_session_extension.cc b/base-nova/src/core/cpu_session_extension.cc index 7aff4fdc9..5dddb19c3 100644 --- a/base-nova/src/core/cpu_session_extension.cc +++ b/base-nova/src/core/cpu_session_extension.cc @@ -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::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::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::Guard + thread(_thread_ep->lookup_and_lock(thread_cap)); if (!thread || !thread->platform_thread()) return; diff --git a/base-nova/src/core/include/cpu_session_component.h b/base-nova/src/core/include/cpu_session_component.h index d68ae9952..9491c961e 100644 --- a/base-nova/src/core/include/cpu_session_component.h +++ b/base-nova/src/core/include/cpu_session_component.h @@ -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 - (_thread_ep->obj_by_cap(thread)); } - /** * Raw thread-killing functionality * diff --git a/base-okl4/src/base/pager/pager.cc b/base-okl4/src/base/pager/pager.cc index 51c1ef4c3..a9817484b 100644 --- a/base-okl4/src/base/pager/pager.cc +++ b/base-okl4/src/base/pager/pager.cc @@ -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::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); } diff --git a/base-okl4/src/core/core_rm_session.cc b/base-okl4/src/core/core_rm_session.cc index 6e7f413d5..9d786d698 100644 --- a/base-okl4/src/core/core_rm_session.cc +++ b/base-okl4/src/core/core_rm_session.cc @@ -26,7 +26,7 @@ Core_rm_session::attach(Dataspace_capability ds_cap, size_t size, { using namespace Okl4; - Dataspace_component *ds = static_cast(_ds_ep->obj_by_cap(ds_cap)); + Object_pool::Guard ds(_ds_ep->lookup_and_lock(ds_cap)); if (!ds) throw Invalid_dataspace(); diff --git a/base-okl4/src/core/okl4_pd_session_component.cc b/base-okl4/src/core/okl4_pd_session_component.cc index 5f2950305..e7cd2bfd1 100644 --- a/base-okl4/src/core/okl4_pd_session_component.cc +++ b/base-okl4/src/core/okl4_pd_session_component.cc @@ -21,8 +21,8 @@ using namespace Genode; void Pd_session_component::space_pager(Thread_capability thread) { - Cpu_thread_component *cpu_thread = dynamic_cast - (_thread_ep->obj_by_cap(thread)); + Object_pool::Guard + cpu_thread(_thread_ep->lookup_and_lock(thread)); if (!cpu_thread) return; _pd.space_pager(cpu_thread->platform_thread()); } diff --git a/base-pistachio/src/base/pager/pager.cc b/base-pistachio/src/base/pager/pager.cc index bb5dfdc6a..3d051ce83 100644 --- a/base-pistachio/src/base/pager/pager.cc +++ b/base-pistachio/src/base/pager/pager.cc @@ -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::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); } diff --git a/base/include/base/object_pool.h b/base/include/base/object_pool.h index 77c4bbe4a..eef492df1 100644 --- a/base/include/base/object_pool.h +++ b/base/include/base/object_pool.h @@ -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 + explicit Guard(X * object) { + _object = dynamic_cast(object); } + + ~Guard() + { + if (!_object) return; + + _object->release(); + } + }; + class Entry : public Avl_node { 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; + /** + * 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()); } /** diff --git a/base/include/base/rpc_server.h b/base/include/base/rpc_server.h index 27761620f..740851542 100644 --- a/base/include/base/rpc_server.h +++ b/base/include/base/rpc_server.h @@ -180,26 +180,10 @@ namespace Genode { class Rpc_object_base : public Object_pool::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 * diff --git a/base/include/root/component.h b/base/include/root/component.h index 48aefe5c1..ab03d6d95 100644 --- a/base/include/root/component.h +++ b/base/include/root/component.h @@ -223,9 +223,8 @@ namespace Genode { { if (!args.is_valid_string()) throw Root::Invalid_args(); - SESSION_TYPE *s = - dynamic_cast(_ep->obj_by_cap(session)); - + typedef typename Object_pool::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(_ep->obj_by_cap(session)); - + SESSION_TYPE * s = + dynamic_cast(_ep->lookup_and_lock(session)); if (!s) return; /* let the entry point forget the session object */ diff --git a/base/src/base/child/child.cc b/base/src/base/child/child.cc index bbec00256..2ca516e4e 100644 --- a/base/src/base/child/child.cc +++ b/base/src/base/child/child.cc @@ -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::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"); diff --git a/base/src/base/server/common.cc b/base/src/base/server/common.cc index e45cc8b59..b3ce211c9 100644 --- a/base/src/base/server/common.cc +++ b/base/src/base/server/common.cc @@ -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()); diff --git a/base/src/base/server/server.cc b/base/src/base/server/server.cc index a246f4bc8..5522ef27c 100644 --- a/base/src/base/server/server.cc +++ b/base/src/base/server/server.cc @@ -66,22 +66,23 @@ void Rpc_entrypoint::entry() srv.ret(ERR_INVALID_OBJECT); /* atomically lookup and lock referenced object */ + Object_pool::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' */ diff --git a/base/src/core/cpu_session_component.cc b/base/src/core/cpu_session_component.cc index b644c1d4b..23fcede4c 100644 --- a/base/src/core/cpu_session_component.cc +++ b/base/src/core/cpu_session_component.cc @@ -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(_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::Guard thread(_thread_ep->lookup_and_lock(thread_cap)); if (!thread) return -1; - Pager_object *p = dynamic_cast(_pager_ep->obj_by_cap(pager_cap)); + Object_pool::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::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::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::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::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::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::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::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::Guard thread(_thread_ep->lookup_and_lock(thread_cap)); if (!thread) return; thread->platform_thread()->affinity(cpu); diff --git a/base/src/core/include/core_rm_session.h b/base/src/core/include/core_rm_session.h index 6940654e6..1f9877948 100644 --- a/base/src/core/include/core_rm_session.h +++ b/base/src/core/include/core_rm_session.h @@ -41,7 +41,8 @@ namespace Genode { Local_addr local_addr = 0, bool executable = false) { - Dataspace_component *ds = static_cast(_ds_ep->obj_by_cap(ds_cap)); + Object_pool::Guard + ds(_ds_ep->lookup_and_lock(ds_cap)); if (!ds) throw Invalid_dataspace(); diff --git a/base/src/core/include/cpu_session_component.h b/base/src/core/include/cpu_session_component.h index 9ea97fefc..18c4d7bd1 100644 --- a/base/src/core/include/cpu_session_component.h +++ b/base/src/core/include/cpu_session_component.h @@ -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 - (_thread_ep->obj_by_cap(thread)); } - /** * Raw thread-killing functionality * diff --git a/base/src/core/pd_session_component.cc b/base/src/core/pd_session_component.cc index 7c2b0b8de..cd5be28e0 100644 --- a/base/src/core/pd_session_component.cc +++ b/base/src/core/pd_session_component.cc @@ -26,8 +26,7 @@ using namespace Genode; int Pd_session_component::bind_thread(Thread_capability thread) { - Cpu_thread_component *cpu_thread = dynamic_cast - (_thread_ep->obj_by_cap(thread)); + Object_pool::Guard cpu_thread(_thread_ep->lookup_and_lock(thread)); if (!cpu_thread) return -1; if (cpu_thread->bound()) { diff --git a/base/src/core/ram_session_component.cc b/base/src/core/ram_session_component.cc index 3b692dab1..22ee41803 100644 --- a/base/src/core/ram_session_component.cc +++ b/base/src/core/ram_session_component.cc @@ -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(_ds_ep->obj_by_cap(ds)); - + Object_pool::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(_ds_ep->obj_by_cap(ds_cap))); + Dataspace_component * ds = + dynamic_cast(_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_ep->obj_by_cap(ram_session_cap)); + Object_pool::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_ep->obj_by_cap(ram_session_cap)); + Object_pool::Guard dst(_ram_session_ep->lookup_and_lock(ram_session_cap)); return _transfer_quota(dst, amount); } diff --git a/base/src/core/rm_session_component.cc b/base/src/core/rm_session_component.cc index 867a96bb3..988c363c8 100644 --- a/base/src/core/rm_session_component.cc +++ b/base/src/core/rm_session_component.cc @@ -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 - (_ds_ep->obj_by_cap(ds_cap)); + Object_pool::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::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 - (_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 - (_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::Guard + cpu_thread(_thread_ep->lookup_and_lock(thread_cap)); + if (cpu_thread) + cpu_thread->platform_thread()->pager(0); + } + _lock.lock(); } diff --git a/base/src/core/signal_session_component.cc b/base/src/core/signal_session_component.cc index d21c168eb..e4e127aa7 100644 --- a/base/src/core/signal_session_component.cc +++ b/base/src/core/signal_session_component.cc @@ -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 - (_context_ep->obj_by_cap(context_cap)); - + Signal_context_component * context = + dynamic_cast(_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 - (_context_ep->obj_by_cap(context_cap)); - + Object_pool::Guard + context(_context_ep->lookup_and_lock(context_cap)); if (!context) { /* * We do not use PWRN() to enable the build system to suppress this diff --git a/os/src/drivers/pci/pci_session_component.h b/os/src/drivers/pci/pci_session_component.h index 63d4e35de..cc1001bc5 100644 --- a/os/src/drivers/pci/pci_session_component.h +++ b/os/src/drivers/pci/pci_session_component.h @@ -156,8 +156,8 @@ namespace Pci { Config_access config_access; /* lookup device component for previous device */ - Device_component *prev = dynamic_cast - (_ep->obj_by_cap(prev_device)); + Genode::Object_pool::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 - (_ep->obj_by_cap(device_cap)); + (_ep->lookup_and_lock(device_cap)); if (!device) return; diff --git a/os/src/drivers/timer/foc/timer_session_component.h b/os/src/drivers/timer/foc/timer_session_component.h index b7e6bc420..1fa993449 100644 --- a/os/src/drivers/timer/foc/timer_session_component.h +++ b/os/src/drivers/timer/foc/timer_session_component.h @@ -98,7 +98,9 @@ namespace Timer { */ bool belongs_to(Genode::Session_capability cap) { - return _entrypoint.obj_by_cap(cap) == this; + Genode::Object_pool::Guard + lcap(_entrypoint.lookup_and_lock(cap)); + return lcap == this; } /** diff --git a/os/src/drivers/timer/nova/timer_session_component.h b/os/src/drivers/timer/nova/timer_session_component.h index 6cffa22b3..4c88db83e 100644 --- a/os/src/drivers/timer/nova/timer_session_component.h +++ b/os/src/drivers/timer/nova/timer_session_component.h @@ -165,7 +165,9 @@ namespace Timer { */ bool belongs_to(Genode::Session_capability cap) { - return _entrypoint.obj_by_cap(cap) == this; + Genode::Object_pool::Guard + lcap(_entrypoint.lookup_and_lock(cap)); + return lcap == this; } /** diff --git a/os/src/server/loader/main.cc b/os/src/server/loader/main.cc index d6b33afe9..f8e921994 100644 --- a/os/src/server/loader/main.cc +++ b/os/src/server/loader/main.cc @@ -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); diff --git a/os/src/server/mixer/mixer.cc b/os/src/server/mixer/mixer.cc index d2a68075b..40a433552 100644 --- a/os/src/server/mixer/mixer.cc +++ b/os/src/server/mixer/mixer.cc @@ -235,8 +235,8 @@ namespace Audio_out { void sync_session(Session_capability audio_out_session) { - Session_component *sc = dynamic_cast - (audio_out_ep()->obj_by_cap(audio_out_session)); + Object_pool::Guard + sc(audio_out_ep()->lookup_and_lock(audio_out_session)); /* check if recipient is a valid session component */ if (!sc) return; diff --git a/os/src/server/nitpicker/genode/main.cc b/os/src/server/nitpicker/genode/main.cc index d8bb14e97..5cdb238f5 100644 --- a/os/src/server/nitpicker/genode/main.cc +++ b/os/src/server/nitpicker/genode/main.cc @@ -411,8 +411,7 @@ class View_component : public Genode::List::Element, int stack(Nitpicker::View_capability neighbor_cap, bool behind, bool redraw) { - View_component *nvc; - nvc = dynamic_cast(_ep->obj_by_cap(neighbor_cap)); + Genode::Object_pool::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(_ep->obj_by_cap(view_cap)); + View_component *vc = dynamic_cast(_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(_ep->obj_by_cap(view_cap)); + Genode::Object_pool::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(_ep->obj_by_cap(view_cap)); + Genode::Object_pool::Guard vc(_ep->lookup_and_lock(view_cap)); ::Session::background(vc->view()); /* switch background view to background mode */ diff --git a/os/src/server/terminal_crosslink/terminal_session_component.cc b/os/src/server/terminal_crosslink/terminal_session_component.cc index f730fd3fd..6f45fd7d5 100644 --- a/os/src/server/terminal_crosslink/terminal_session_component.cc +++ b/os/src/server/terminal_crosslink/terminal_session_component.cc @@ -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::Guard session(_ep.lookup_and_lock(cap)); + return session == this; } diff --git a/ports/src/app/gdb_monitor/app_child.h b/ports/src/app/gdb_monitor/app_child.h index cf37d64d4..682379176 100644 --- a/ports/src/app/gdb_monitor/app_child.h +++ b/ports/src/app/gdb_monitor/app_child.h @@ -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); diff --git a/ports/src/app/gdb_monitor/rm_session_component.cc b/ports/src/app/gdb_monitor/rm_session_component.cc index e1795bf50..cce347586 100644 --- a/ports/src/app/gdb_monitor/rm_session_component.cc +++ b/ports/src/app/gdb_monitor/rm_session_component.cc @@ -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::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); diff --git a/ports/src/noux/dataspace_registry.h b/ports/src/noux/dataspace_registry.h index 20ea97300..1fea6d5c6 100644 --- a/ports/src/noux/dataspace_registry.h +++ b/ports/src/noux/dataspace_registry.h @@ -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); } }; } diff --git a/ports/src/noux/local_rm_service.h b/ports/src/noux/local_rm_service.h index f79286634..1e72de8c5 100644 --- a/ports/src/noux/local_rm_service.h +++ b/ports/src/noux/local_rm_service.h @@ -120,9 +120,8 @@ namespace Noux { void close(Genode::Session_capability session) { - Rm_session_component *rm_session = - dynamic_cast(_ep.obj_by_cap(session)); - + Object_pool::Guard + rm_session(_ep.lookup_and_lock(session)); if (!rm_session) { PWRN("Unexpected call of close with non-RM-session argument"); return; diff --git a/ports/src/noux/rm_session_component.h b/ports/src/noux/rm_session_component.h index 5273bc636..9a97ee457 100644 --- a/ports/src/noux/rm_session_component.h +++ b/ports/src/noux/rm_session_component.h @@ -107,7 +107,7 @@ namespace Noux { Dataspace_capability ds; - Dataspace_info *info = _ds_registry.lookup_info(curr->ds); + Object_pool::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::Guard info(_ds_registry.lookup_info(region->ds)); if (!info) { PERR("attempt to write to unknown dataspace type"); for (;;);