Hallo Stefan, thank you for your extensive answer. It helped me a lot. I will talk about your advice to implement the mechanism in user-space of Genode with my advisor.
But if I have to implement it in core, how can I find an object in the object pool? * Publicly, it has only the insert, remove, and apply functionality. * Privatly, it uses an Avl_tree<Entry> structure and a method called find_by_obj_id(unsigned long obj_id) in Entry. Can I use this method to find my object? And how do I get the obj_id of a specific PD session with a certain label? Kind regards Denis On 02.08.2016 11:20, Stefan Kalkowski wrote: > Hello Denis, > > On 07/29/2016 12:15 PM, Denis Huber wrote: >> Dear Genode community, >> >> I want to implement a new service (class Cr_session) residing in core >> which provides an Rpc method to checkpoint the state of a specific >> component (given its label string). I am using Genode 16.05 and the foc >> kernel (pbxa9 build). The first step is to store the content of the >> address space of the compoent. My approach is the following: >> >> 1) First a test component is created which shall be checkpointed. The >> component counts an integer every second. >> >> In base/src/test/cr_service/counter/main.cc (newly created file): >> !void Component::construct(Genode::Env &env) >> !{ >> ! unsigned int n = 0; >> ! Timer::Connection timer(env); >> ! >> ! while(1) >> ! { >> ! Genode::log(n); >> ! n++; >> ! timer.msleep(1000); >> ! } >> !} >> >> 2) To realize the CR service in core, I want to find the specific PD >> session of the test component. Therefore a separate Sliced_heap >> exclusively for Pd_session_component objects is created in core's main >> function. >> >> In base/src/core/main.cc: >> !static Sliced_heap pd_sliced_heap(env()->ram_session(), >> env()->rm_session()); >> ![...] >> !static Pd_root pd_root(e, e, pager_ep, &pd_sliced_heap); >> >> 2) The CR service is registered and the special Sliced_heap is passed to >> the Root_component<Cr_session_component> object. >> >> In base/src/core/main.cc: >> !static Cr_root cr_root(e, &sliced_heap, &pd_sliced_heap); >> ![...] >> !static Local_service ls[] = { >> ! Local_service(Cr_session::service_name(), &cr_root), >> ![...] >> !} >> >> 3) In the implementation of the checkpoint method the Sliced_heap >> (stored in _alloced_pds) is searched for a Pd_session_component with a >> specific label string. The class implementing the Cr service >> (Genode::Cr_session_component : Rpc_object<Cr_session>) is a friend >> class in Sliced_heap and is allowed to access the _blocks member >> variable containing the Pd_session_component objects. >> >> In base/src/core/include/cr_session_component.h (newly created file): >> !bool checkpoint(String<64> label) >> !{ >> ! Pd_session_component *pd = nullptr; >> ! bool found = false; >> ! Sliced_heap::Block *b = _alloced_pds->_blocks.first(); >> ! for(; (b != 0) && !found; b = b->next()) >> ! { >> ! pd = reinterpret_cast<Pd_session_component*>(b + 1); >> ! if(label == pd->_label.string) found = true; >> ! } >> > > I would strongly recommend to not use the heap abstraction for > retrieving any objects. Your implementation is extremely error-prone > when depending on internals of the Sliced_heap implementation, and > indiscriminately casting to some objects. It would be much better to > retrieve the PD object either by running through the object pool where > they reside in, or if you do not want that for some reason, register > them in a special data-structure to retrieve them more easily, e.g., a list. > >> 4) The Pd_session_component object is known and now it shall be used to >> access the test component's address space content. To retrieve the >> content I want to attach the Dataspace of the component's Region_map to >> core's Region_map. >> >> In base/src/core/include/cr_session_component.h (newly created file): >> ! Capability<Region_map> rm_cap = pd->address_space(); >> ! Region_map_client rm_client(rm_cap); >> ! void* addr = core_env()->rm_session()->attach(rm_client.dataspace()); >> ! return true; >> !} >> >> 5) After invoking rm_client.dataspace() the Rpc method never returns and >> the test scenario times out. >> >> What am I doing wrong? I compared the source code of other core services >> with the CR service and found no usage of classes derived from >> Rpc_client belonging to other core services. Is it not possible to use >> Rpc methods in core? > > In general, it is possible to use RPC functions within core, but if you > call a core-service itself within the execution context that provides > these services you fall into a deadlock. Your new service probably uses > the same entrypoint (thereby execution context) like for instance the RM > service. So then it is not possible to invoke this service via RPC calls > from your context. > >> >> I tested another solution where I only use Rpc_objects directly. I used >> pd_session_component::address_space_region_map() to access the >> address_space directly, where I think to find the memory content of the >> test component (Please correct me, if I am wrong). >> The following listing replaces the listing in step 4. >> >> In base/src/core/include/cr_session_component.h (newly created file): >> ! Dataspace_capability ds_cap = >> pd->address_space_region_map().dataspace(); >> ! char* addr = core_env()->rm_session()->attach(ds_cap); >> ! log("Attaching dataspace: Returned pointer: ", addr); >> ! >> ! Dataspace_component *ds_comp = >> pd->address_space_region_map().dataspace_component(); >> ! log("Reading dataspace component"); >> ! log("phys_addr = ", ds_comp->phys_addr(), " size = ", >> ds_comp->size(), " writable = ", ds_comp->writable() ? "true" : "false"); >> >> The output of the log function was the following: >> Attaching dataspace: Returned pointer: 0x00000000 >> Reading dataspace component >> phys_addr = 0 size = 3221221376 writable = false >> >> Now I got a null pointer and cannot read the content of the Region_map >> of the test component. >> >> >> Can someone help me to answer the following questions: >> * Can I use Capability invokation in core, where the Rpc_object belongs >> to another core service? If yes, how? Perhaps, my problem is the correct >> retrieval of the Pd_session_component, thus I can invalid Capabilities. >> * Why do I get an invalid pointer from the attach method of core's >> Region_map? Is it not allowed to attach dataspaces in core? Are they >> already attached in core, and I only need the pointer to the memory? Is >> the Dataspace_capability invalid? > > As already mentioned, you can call core services within core, but only > from a different execution context than the entrypoint itself, which > implements the core services. Anyway this is not recommended in general, > because you can easily produce circular dependencies. > > The correct retrieval of PD components indeed is a problem given your > example. As already explained it is not recommended at all to use the > memory allocator to find objects. This practice is not related to Genode > specifically. > > You can of course attach dataspaces in core. This is used for instance > before core hands out a dataspace when clearing its content. > Nevertheless, when it comes to non-physical dataspaces, which means not > simple dataspaces representing only physical memory, e.g., the > representation of a region-map, you cannot simply attach them within > core. The reason is that core's RM service implementation is much > simpler than the one core provides for all other components, again due > to possible circular dependencies. When you attach a dataspace in core, > the corresponding memory mappings are established immediately. For all > other components than core, a pager service within core resolves > page-faults lazily when they occur. Thereby, more complex dataspaces > like the region map representation are identified too. > > I would strongly recommend to you to *not* implement your > checkpoint-service within core. It is far more easy to write an extra > component, which wraps the relevant core services, e.g. PD, RM etc.. > That component can hold the capabilities to the relevant core services > in a data-structure that matches your demands. You won't run into > trouble of circular dependencies. You can easily attach region map > representations to its region map, etc.. > You can route all relevant services to that component instead of core. > If you really want to target all components you could even place your > component underneath of the init component. Thereby, you can use most > currently available run-scripts with minor changes only. > > Best regards > Stefan > >> >> >> Kind regards >> Denis >> >> >> ------------------------------------------------------------------------------ >> _______________________________________________ >> genode-main mailing list >> genode-main@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/genode-main >> > ------------------------------------------------------------------------------ _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main