Hi,
I'm trying to port some code that I originally implemented in Iguana. This functionality pertains to profiling functionality. In my current setup (ie. with Iguana), I added an L4 system call (OKL4) to start and stop profiling. I'm wondering whether it's possible at all to use OKL4 functionality directly in writing genode apps. The profiling code that I have implemented is L4 code, where some of the code uses OKL4 IPC primitives and a small amount of Iguana based code with regards to creating threads.
Any help on this would be greatly appreciated.
Thanks Peter N
Hi Peter,
I'm trying to port some code that I originally implemented in Iguana. This functionality pertains to profiling functionality. In my current setup (ie. with Iguana), I added an L4 system call (OKL4) to start and stop profiling. I'm wondering whether it's possible at all to use OKL4 functionality directly in
yes, that is no problem. In fact, Genode's framework libraries such as the IPC library directly use L4 system calls. Also, our port of OKLinux relies on using L4 system calls directly. However, all programs except for Genode's core do not have roottask privileges. So you are restricted to use system calls that need no special privileges. As a general rule of thumb, I would suggest to perform all tasks that are related to resource allocation (e.g., creating threads and address spaces) and address-space layout management (mapping) using Genode primitives only.
If you want to use OKL4 system calls from your program, you might take some existing Genode code as reference, for example the IPC library:
base-okl4/src/base/ipc/ipc.cc
There you can see that we include the OKL4 headers into a dedicated namespace called 'Okl4'. I suggest to stick to this scheme to avoid symbol-name conflicts between your code and the Genode libraries.
writing genode apps. The profiling code that I have implemented is L4 code, where some of the code uses OKL4 IPC primitives and a small amount of Iguana based code with regards to creating threads.
It should be ok to use OKL4 directly for your L4-specific IPC operations and your custom system-call interface. For thread creation, however, Genode's Thread API should be used.
Regards Norman
Norman,
Thanks for your help as usual. With my code, I have functionality that is based on the iguana trace buffer. As such, some of my functionality is iguana based. In particular, I am wondering how i can go about mapping kernel memory to user space in a way that works the same as the Iguana trace buffer, given you have suggested that Genode primitives should be used.
Thanks ----------------------------------------------------- Peter Nguyen Jacaranda Research Group
On 11/01/2010, at 7:02 PM, Norman Feske wrote:
Hi Peter,
I'm trying to port some code that I originally implemented in Iguana. This functionality pertains to profiling functionality. In my current setup (ie. with Iguana), I added an L4 system call (OKL4) to start and stop profiling. I'm wondering whether it's possible at all to use OKL4 functionality directly in
yes, that is no problem. In fact, Genode's framework libraries such as the IPC library directly use L4 system calls. Also, our port of OKLinux relies on using L4 system calls directly. However, all programs except for Genode's core do not have roottask privileges. So you are restricted to use system calls that need no special privileges. As a general rule of thumb, I would suggest to perform all tasks that are related to resource allocation (e.g., creating threads and address spaces) and address-space layout management (mapping) using Genode primitives only.
If you want to use OKL4 system calls from your program, you might take some existing Genode code as reference, for example the IPC library:
base-okl4/src/base/ipc/ipc.cc
There you can see that we include the OKL4 headers into a dedicated namespace called 'Okl4'. I suggest to stick to this scheme to avoid symbol-name conflicts between your code and the Genode libraries.
writing genode apps. The profiling code that I have implemented is L4 code, where some of the code uses OKL4 IPC primitives and a small amount of Iguana based code with regards to creating threads.
It should be ok to use OKL4 directly for your L4-specific IPC operations and your custom system-call interface. For thread creation, however, Genode's Thread API should be used.
Regards Norman
This SF.Net email is sponsored by the Verizon Developer Community Take advantage of Verizon's best-in-class app development support A streamlined, 14 day to market process makes app distribution fast and easy Join now and get one step closer to millions of Verizon customers http://p.sf.net/sfu/verizon-dev2dev _______________________________________________ Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Peter,
Thanks for your help as usual. With my code, I have functionality that is based on the iguana trace buffer. As such, some of my functionality is iguana based. In particular, I am wondering how i can go about mapping kernel memory to user space in a way that works the same as the Iguana trace buffer, given you have suggested that Genode primitives should be used.
the best way to go for mapping a predefined physical memory area into a Genode process is using core's IO_MEM service because, logically, this memory can be seen as device memory. When opening an IO_MEM session (see 'base/include/io_mem_session/connection.h'), you can specify the physical base address and the size of the physical memory resource. You can then request a dataspace capability from this session and use it for attaching the memory to the local address space (via 'env()->rm_session()->attach()'). For an example of using the IO_MEM service, please have a look at the GTA01 platform driver, which relies on this procedure to access platform registers:
os/src/drivers/platform/gta01/main.cc
Please make sure that your trace buffer is outside the normal RAM configured in the elfweaver config file because core will refuse to hand out memory as IO_MEM when this memory is reported as normal RAM. To see the physical memory considered as normal RAM, you can enable the 'verbose_boot_info' flag in 'base-okl4/src/core/platform.cc'.
Regards Norman
Norman,
To clarify what i'm doing, I've implemented a profiling environment that runs on top of L4. More specifically, this profiling environment has adaptive properties, where the profiling environment can react whenever certain events occur. Currently, I've implemented this on top of Iguana, but in terms of experimentation, there isn't a great deal that I can do. The interface to this environment is a language, where the user expresses the profiling strategies that should be used under certain circumstances. Currently, the language is converted to L4 C code.
The reason why I'm looking at genode was that there was an implementation of a HTTP server. I'd like to be able to use my language/profiling environment so that it can monitor activity in terms of CPU usage, and also network usage, given the IP stack. What do you think would be the best way to "link" my profiling environment with Genode, given that virtually all the profiling code is L4 based (there is some Iguana functionality as i mentioned before, but this code can easily be converted to L4 code). I was thinking that it could be implemented as part of the test suite (I've noticed a couple of test folders that provide implementations of pagers and what not), where profiling begins upon boot up, and then somehow providing a link between genode and my profiling environment.
Peter
Quoting Norman Feske <norman.feske@...1...>:
Hi Peter,
I'm trying to port some code that I originally implemented in Iguana. This functionality pertains to profiling functionality. In my current setup (ie.
with
Iguana), I added an L4 system call (OKL4) to start and stop profiling. I'm wondering whether it's possible at all to use OKL4 functionality directly
in
yes, that is no problem. In fact, Genode's framework libraries such as the IPC library directly use L4 system calls. Also, our port of OKLinux relies on using L4 system calls directly. However, all programs except for Genode's core do not have roottask privileges. So you are restricted to use system calls that need no special privileges. As a general rule of thumb, I would suggest to perform all tasks that are related to resource allocation (e.g., creating threads and address spaces) and address-space layout management (mapping) using Genode primitives only.
If you want to use OKL4 system calls from your program, you might take some existing Genode code as reference, for example the IPC library:
base-okl4/src/base/ipc/ipc.cc
There you can see that we include the OKL4 headers into a dedicated namespace called 'Okl4'. I suggest to stick to this scheme to avoid symbol-name conflicts between your code and the Genode libraries.
writing genode apps. The profiling code that I have implemented is L4 code, where some of the code uses OKL4 IPC primitives and a small amount of
Iguana
based code with regards to creating threads.
It should be ok to use OKL4 directly for your L4-specific IPC operations and your custom system-call interface. For thread creation, however, Genode's Thread API should be used.
Regards Norman
This SF.Net email is sponsored by the Verizon Developer Community Take advantage of Verizon's best-in-class app development support A streamlined, 14 day to market process makes app distribution fast and easy Join now and get one step closer to millions of Verizon customers http://p.sf.net/sfu/verizon-dev2dev _______________________________________________ Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Peter,
thanks for providing more insight into your work. With the workload on Genode getting more and more sophisticated with each release, profiling becomes increasingly important to us. So your work in this direction is much appreciated. :-)
I know too little about the structure of your profiling environment to give a clear advice on how to integrate it with Genode. The answer depends on the relationship between the user-level portion of your profiling environment and the other processes. If there is no interaction (only interaction with the kernel) and the profiling takes place at a global level (e.g., monitoring the IPC traffic between all processes), the profiling process could be started just alongside the other programs by the init process. But I assume that the profiling environment somehow has to interact with the rest of the system, for example for presenting the profiling result or for getting activated in the first place.
Another setting would be to apply profiling as a tool to analyse a Genode subsystem only. This could be achieved by letting the profiler play the role of the parent of this subsystem (similar to init). This way, all requests of the subsystem to the outside will become visible to the profiler at the Genode API level. For example, if the subsystem creates a new process, it will ask the parent (which is then the profiler) to create the corresponding CPU, PD, and RAM sessions. So the profiler can observe how the subsystem interacts with the outside and, in principle, virtualize all services used by the subsystem, or just delegate requests further to the profiler's parent. This way, the profiler could obtain much higher level information about the system than plain kernel events.
Regarding the question about how to integrate your source code with Genode, I recommend creating a dedicated repository for your work rather than modifying the existing source code. You are free to define the structure of your repository. Usually we have a layout such as
repo/include - public interfaces usable by other repositories repo/lib/mk - library description files usable from programs of other repositories repo/src/server - source codes of services repo/src/lib - source codes of libraries repo/src/app - source codes of applications repo/src/test - source codes for test programs repo/tool - tools and scripts specific for the repository repo/doc - documentation
Whether your profiler belongs to 'src/server' or 'src/app' depends on role it plays within Genode (does it provide a service RPC interface or not?).
The reason why I'm looking at genode was that there was an implementation of a HTTP server. I'd like to be able to use my language/profiling environment so that it can monitor activity in terms of CPU usage, and also network usage, given the IP stack. What do you think would be the best way to "link" my profiling environment with Genode, given that virtually all the profiling code is L4 based (there is some Iguana functionality as i mentioned before, but this code can easily be converted to L4 code). I was thinking that it could be implemented as part of the test suite (I've noticed a couple of test folders that provide implementations of pagers and what not), where profiling begins upon boot up, and then somehow providing a link between genode and my profiling environment.
Can you elaborate why the profiling code is tied to L4? Would it be possible to generalize it? I ask because a general profiling infra- structure would be valuable not only on OKL4 but also on the other platforms.
Apart from the networking example, I think there are plenty of workloads on Genode that are worth to inspect in detail. For example, how does Qt4 interact with Genode and are there opportunities for performance optimizations? Or how interplays Genode's signalling API with the OKL4 scheduler? Or how much latency overhead do we have for each interrupt delivered via Genodes IRQ service? A profiling framework could provide answers to these and many more interesting questions.
Regards Norman
Norman,
I know too little about the structure of your profiling environment to give a clear advice on how to integrate it with Genode. The answer depends on the relationship between the user-level portion of your profiling environment and the other processes. If there is no interaction (only interaction with the kernel) and the profiling takes place at a global level (e.g., monitoring the IPC traffic between all processes), the profiling process could be started just alongside the other programs by the init process. But I assume that the profiling environment somehow has to interact with the rest of the system, for example for presenting the profiling result or for getting activated in the first place.
My profiling environment makes use of sampling, where samples are taken of the system execution. These samples are generated in the microkernel as they are based on the timer interrupt within the kernel. The samples are then copied to buffers in user space. Basically, the data that can be collected only pertains to kernel "related" information. If I had more time with my project (which is a Masters project), I would have provided more functionality pertaining to user-space functionality. At this time though, I only really want to focus on the network functionality with regards to experimentation.
Another setting would be to apply profiling as a tool to analyse a Genode subsystem only. This could be achieved by letting the profiler play the role of the parent of this subsystem (similar to init). This way, all requests of the subsystem to the outside will become visible to the profiler at the Genode API level. For example, if the subsystem creates a new process, it will ask the parent (which is then the profiler) to create the corresponding CPU, PD, and RAM sessions. So the profiler can observe how the subsystem interacts with the outside and, in principle, virtualize all services used by the subsystem, or just delegate requests further to the profiler's parent. This way, the profiler could obtain much higher level information about the system than plain kernel events.
That would be very useful for profiling Genode, but as I mentioned before, I don't really have any time to consider this.
Can you elaborate why the profiling code is tied to L4? Would it be possible to generalize it? I ask because a general profiling infra- structure would be valuable not only on OKL4 but also on the other platforms.
I am very aware that generalising my profiling infrastructure would be very valuable, but time constraints prevent me from doing such work. My implementation of the profiling environment was only based on L4/Iguana, and using Wombat as part of testing. I have been looking into Genode as of late due to the other functionality that is already available eg. HTTP server. Also, I figured that porting the user-space portion should be relatively easy to do, since all i would need to worry about is copying the samples to user space. I'm assuming here that Genode is similar to Iguana, but with significantly more functionality than Iguana.
Peter
Hi,
Is it at all possible to make use of functions like malloc, memcpy, strlen, and other "standard" C functions in Genode apps?
Peter
Hi,
In trying to compile some code, i keep getting the following errors when i try to instantiate a genode thread:
undefined reference to `operator new[](unsigned int)'
Can I not use "new" to allocate memory? If not, what is the proper way of doing this via Genode?
Peter
PS. I noticed upon further inspection that a '-nostdlib' flag is used when linking, which suggests to me that "new" does not work at all.
Hi Peter,
In trying to compile some code, i keep getting the following errors when i try to instantiate a genode thread:
undefined reference to `operator new[](unsigned int)'
Can I not use "new" to allocate memory? If not, what is the proper way of doing this via Genode?
the default 'new' and 'delete' are not provided by the framework to raise awareness about memory allocations. The problem of the default new operator is that it leaves open the question to whom the allocated memory should be accounted. For example, a server that uses 'new' on behalf of client requests would make its own heap usage dependent on client behaviour and prone to resource-denial-of-service problems. In Genode, we promote the concept that such a server allocates such memory from a client-specific heap partition. More background information is provided here
http://genode.org/documentation/architecture/framework#Heap_partitioning
Because the standard 'new' operator does not support the concept of heap partitions, we only provide a special 'new' operator that takes an 'Allocator' as argument. This way, the programmer must specify where to take the memory from. To allocate an object from the applications own heap, you can use the heap allocator provided by the process environment:
A *a = new (Genode::env()->heap()) A(constructor_argument)
For destructing the object 'a', the allocator must be specified as well. Because this is not possible with the delete operator, we provide a 'destroy' template in 'include/base/allocator.h'. Instead of 'delete a' use:
destroy(Genode::env()->heap(), a)
Despite of Genode not supporting standard 'new' and 'delete' by intention, it is relatively easy to create those operators out of the building blocks provided by Genode. For doing so, you may take a look at the following examples:
os/src/drivers/framebuffer/vesa/main.cc demo/src/app/scout/genode/platform_genode.cc (line 78)
Norman
Hi Peter,
when using 'destroy' you need to be aware of using the concrete class of the object you want to delete, otherwise dependend on the concrete allocator, it might not know how much memory needs to be freed.
regards stefan
On Thursday, 28. January 2010 10:53:54 Norman Feske wrote:
Hi Peter,
In trying to compile some code, i keep getting the following errors when i try to instantiate a genode thread:
undefined reference to `operator new[](unsigned int)'
Can I not use "new" to allocate memory? If not, what is the proper way of doing this via Genode?
the default 'new' and 'delete' are not provided by the framework to raise awareness about memory allocations. The problem of the default new operator is that it leaves open the question to whom the allocated memory should be accounted. For example, a server that uses 'new' on behalf of client requests would make its own heap usage dependent on client behaviour and prone to resource-denial-of-service problems. In Genode, we promote the concept that such a server allocates such memory from a client-specific heap partition. More background information is provided here
http://genode.org/documentation/architecture/framework#Heap_partitioning
Because the standard 'new' operator does not support the concept of heap partitions, we only provide a special 'new' operator that takes an 'Allocator' as argument. This way, the programmer must specify where to take the memory from. To allocate an object from the applications own heap, you can use the heap allocator provided by the process environment:
A *a = new (Genode::env()->heap()) A(constructor_argument)
For destructing the object 'a', the allocator must be specified as well. Because this is not possible with the delete operator, we provide a 'destroy' template in 'include/base/allocator.h'. Instead of 'delete a' use:
destroy(Genode::env()->heap(), a)
Despite of Genode not supporting standard 'new' and 'delete' by intention, it is relatively easy to create those operators out of the building blocks provided by Genode. For doing so, you may take a look at the following examples:
os/src/drivers/framebuffer/vesa/main.cc demo/src/app/scout/genode/platform_genode.cc (line 78)
Norman
--- The Planet: dedicated and managed hosting, cloud storage, colocation Stay online with enterprise data centers and the best network in the business Choose flexible plans and management services without long-term contracts Personal 24x7 support from experience hosting pros just a phone call away. http://p.sf.net/sfu/theplanet-com _______________________________________________ Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi,
In also trying to create a thread, there are some instances when i would like to pass some parameters to a thread to establish a starting state for a thread. To do this, the class i write, which inherits from Thread contains some instance variables which get initialised in the class's constructor. From there, when the thread starts execution, the function that executes when the thread starts uses those variables i've declared. However, when I run genode with my app, i keep getting the following message, which seems to result in the thread not executing at all:
no RM attachment (READ pf_addr=562ae410 pf_ip=20145c6 from 08).
The code i have for this thread is the following:
class collection1 : public Thread<4096> { public: L4_ThreadId_t tid_block; void thread_fn(); void entry();
collection1(unsigned long value) { tid_block.raw = value; } };
Yet when i instantiate this class, I get the "no RM attachment" message, which results in this thread not executing at all. Does anyone know what is happening? Can parameters be passed to a thread via its constructor?
Peter
Before I get onto my next question, I would like to thank you Stefan and Norman for all the help you have given me. I hope i haven't been annoying you with all of these questions.
the best way to go for mapping a predefined physical memory area into a Genode process is using core's IO_MEM service because, logically, this memory can be seen as device memory. When opening an IO_MEM session (see 'base/include/io_mem_session/connection.h'), you can specify the physical base address and the size of the physical memory resource. You can then request a dataspace capability from this session and use it for attaching the memory to the local address space (via 'env()->rm_session()->attach()'). For an example of using the IO_MEM service, please have a look at the GTA01 platform driver, which relies on this procedure to access platform registers:
os/src/drivers/platform/gta01/main.cc
Please make sure that your trace buffer is outside the normal RAM configured in the elfweaver config file because core will refuse to hand out memory as IO_MEM when this memory is reported as normal RAM. To see the physical memory considered as normal RAM, you can enable the 'verbose_boot_info' flag in 'base-okl4/src/core/platform.cc'.
In trying to map the buffer that has been allocated in the kernel, I keep getting a page fault, which would suggest that the kernel memory has not been mapped. This sampling buffer always gets allocated at physical address 4456448, while the size of the buffer is 262144. I figured i'd try following the code in that file mentioned above. The code currently have is the following:
enum{SAMP_PHYS = 0x440000, SAMP_SIZE = 0x40000}; Io_mem_connection sampbuffer(SAMP_PHYS, SAMP_SIZE); samples = (sampling_buffer_t*)env()->rm_session()->attach(sampbuffer.dataspace());
where samples is of type sampling_buffer_t*. If you have the iguana source that came with OKL4 v2, this type is the same type as the trace_buffer_t. I strongly suspect this code is not correct for mapping the kernel memory to user space. How can i go about mapping this memory so that I can read the contents of this memory so as to perform processing?
Thanks Peter
Hi Peter,
On Thursday, 28. January 2010 13:00:01 Peter Nguyen wrote:
Hi,
In also trying to create a thread, there are some instances when i would like to pass some parameters to a thread to establish a starting state for a thread. To do this, the class i write, which inherits from Thread contains some instance variables which get initialised in the class's constructor. From there, when the thread starts execution, the function that executes when the thread starts uses those variables i've declared.
That's perfectly fine.
However, when I run genode with my app, i keep getting the following message, which seems to result in the thread not executing at all:
no RM attachment (READ pf_addr=562ae410 pf_ip=20145c6 from 08).
That means one of your threads raised a pagefault. "RM" stands for "region map" a datastructure that manages the mapping of virtual memory regions to a specific dataspace. If there is no region map, that corresponds to a virtual address, the pager is not able to back that virtual address with physical memory and you will get above error message.
To determine where in your code the pagefault occurs you might have a look at the instruction given by the instruction pointer ("pf_ip"), as well as the location in the source code corresponding to that instruction. You can use objdump to have a look at the assembler code together with the corresponding C++ function and object member names:
objdump -dC <your_binary>
When using objdump with the '-C' flag your binary should not be stripped!
The code i have for this thread is the following:
class collection1 : public Thread<4096> { public: L4_ThreadId_t tid_block; void thread_fn(); void entry();
collection1(unsigned long value) { tid_block.raw = value; } };
Well, the most important parts would be the constructor and entry function code as well as the caller's context. Probably the pagefault occurs at one of these locations.
Yet when i instantiate this class, I get the "no RM attachment" message, which results in this thread not executing at all. Does anyone know what is happening? Can parameters be passed to a thread via its constructor?
yes, that's the recommended way.
regards stefan
PS: most mail clients and archive software use the "In-Reply-To" mail header to structure related mails in "threads". If you start a topic with a different subject, it would be nice, if you would not reply to a former mail of the list ;-)
Peter
--- The Planet: dedicated and managed hosting, cloud storage, colocation Stay online with enterprise data centers and the best network in the business Choose flexible plans and management services without long-term contracts Personal 24x7 support from experience hosting pros just a phone call away. http://p.sf.net/sfu/theplanet-com _______________________________________________ Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Peter,
In trying to map the buffer that has been allocated in the kernel, I keep getting a page fault, which would suggest that the kernel memory has not been mapped. This sampling buffer always gets allocated at physical address 4456448, while the size of the buffer is 262144. I figured i'd try following the code in that file mentioned above. The code currently have is the following:
enum{SAMP_PHYS = 0x440000, SAMP_SIZE = 0x40000}; Io_mem_connection sampbuffer(SAMP_PHYS, SAMP_SIZE); samples = (sampling_buffer_t*)env()->rm_session()->attach(sampbuffer.dataspace());
where samples is of type sampling_buffer_t*. If you have the iguana source that came with OKL4 v2, this type is the same type as the trace_buffer_t. I strongly suspect this code is not correct for mapping the kernel memory to user space. How can i go about mapping this memory so that I can read the contents of this memory so as to perform processing?
Is 'sampbuffer' declared as a local variable? If yes, this would explain the problem. When the program leaves the scope where 'sampbuffer' is declared, the destructor of 'Io_mem_connection' gets executed. By default, this destructor closes the session such that the session's dataspace gets destroyed. You can solve this problem in two ways. First, it is possible to tell 'sampbuffer' to keep the session open after the destuctor is called:
sampbuffer.on_destruction(Io_mem_connection::KEEP_OPEN);
Another solution would be declaring 'sampbuffer' als local static variable. Once constructed, one object instance will exist for the whole runtime of the program. Of course, you could also explicitely manage the lifetime of 'sampbuffer' by using the 'new' operator but in most cases (if you need one session during the whole execution time), a declaring the connection object as local static variable is most convenient.
Norman
Is 'sampbuffer' declared as a local variable? If yes, this would explain the problem. When the program leaves the scope where 'sampbuffer' is declared, the destructor of 'Io_mem_connection' gets executed. By default, this destructor closes the session such that the session's dataspace gets destroyed. You can solve this problem in two ways. First, it is possible to tell 'sampbuffer' to keep the session open after the destuctor is called:
sampbuffer.on_destruction(Io_mem_connection::KEEP_OPEN);
Another solution would be declaring 'sampbuffer' als local static variable. Once constructed, one object instance will exist for the whole runtime of the program. Of course, you could also explicitely manage the lifetime of 'sampbuffer' by using the 'new' operator but in most cases (if you need one session during the whole execution time), a declaring the connection object as local static variable is most convenient.
The sampbuffer variable is not declared as a local variable. I have also tried keeping the session open as you suggested, but with no success. Just for the record, the message I keep getting is the following:
no RM attachment (READ pf_addr=20 pf_ip=2001248 from 08)virtual void Genode::Signal_session_component::submit(Genode::Signal_context_capability, unsigned int): invalid signal-context capability
Peter
Whoops, my mistake. The buffer is actually being mapped, there are some things I'm doing wrong at me end. Apologies.
Peter
Quoting Peter Nguyen <peter.nguyen@...29...>:
Is 'sampbuffer' declared as a local variable? If yes, this would explain the problem. When the program leaves the scope where 'sampbuffer' is declared, the destructor of 'Io_mem_connection' gets executed. By default, this destructor closes the session such that the session's dataspace gets destroyed. You can solve this problem in two ways. First, it is possible to tell 'sampbuffer' to keep the session open after the destuctor is called:
sampbuffer.on_destruction(Io_mem_connection::KEEP_OPEN);
Another solution would be declaring 'sampbuffer' als local static variable. Once constructed, one object instance will exist for the whole runtime of the program. Of course, you could also explicitely manage the lifetime of 'sampbuffer' by using the 'new' operator but in most cases (if you need one session during the whole execution time), a declaring the connection object as local static variable is most convenient.
The sampbuffer variable is not declared as a local variable. I have also tried keeping the session open as you suggested, but with no success. Just for the record, the message I keep getting is the following:
no RM attachment (READ pf_addr=20 pf_ip=2001248 from 08)virtual void Genode::Signal_session_component::submit(Genode::Signal_context_capability, unsigned int): invalid signal-context capability
Peter
The Planet: dedicated and managed hosting, cloud storage, colocation Stay online with enterprise data centers and the best network in the business Choose flexible plans and management services without long-term contracts Personal 24x7 support from experience hosting pros just a phone call away. http://p.sf.net/sfu/theplanet-com _______________________________________________ Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi,
So what i'm currently trying to do is that i'm trying to have a thread, whose purpose is to initialize some more genode threads as it results in the page faults for some reason. It seems that Genode doesn't like me creating and starting thread instances by another thread (ie. main creates thread1 -> thread1 creates thread2), which I find weird if in actual fact that this actually is not meant to work. I created and started an instance of thread2 in the main function of my genode server, which resulted in that thread working, whereas creating and starting an instance of thread2 in thread1 does not seem to work. I have a question that may contribute to me coming up with a workaround to this problem. Given that a thread may call a function that belongs to another class, is there any way for me to obtain the ID of the thread that is currently executing? In previous builds of OKL4, L4_Myself() could be used within a function which would return the ID of the thread that was executing when the given function executes.
Peter
Quoting Stefan Kalkowski <stefan.kalkowski@...1...>:
Hi Peter,
On Thursday, 28. January 2010 13:00:01 Peter Nguyen wrote:
Hi,
In also trying to create a thread, there are some instances when i would like to pass some parameters to a thread to establish a starting state for a thread. To do this, the class i write, which inherits from Thread contains some instance variables which get initialised in the class's constructor. From there, when the thread starts execution, the function that executes when the thread starts uses those variables i've declared.
That's perfectly fine.
However, when I run genode with my app, i keep getting the following message, which seems to result in the thread not executing at all:
no RM attachment (READ pf_addr=562ae410 pf_ip=20145c6 from 08).
That means one of your threads raised a pagefault. "RM" stands for "region map" a datastructure that manages the mapping of virtual memory regions to a specific dataspace. If there is no region map, that corresponds to a virtual address, the pager is not able to back that virtual address with physical memory and you will get above error message.
To determine where in your code the pagefault occurs you might have a look at the instruction given by the instruction pointer ("pf_ip"), as well as the location in the source code corresponding to that instruction. You can use objdump to have a look at the assembler code together with the corresponding C++ function and object member names:
objdump -dC <your_binary>
When using objdump with the '-C' flag your binary should not be stripped!
The code i have for this thread is the following:
class collection1 : public Thread<4096> { public: L4_ThreadId_t tid_block; void thread_fn(); void entry();
collection1(unsigned long value) { tid_block.raw = value; } };
Well, the most important parts would be the constructor and entry function code as well as the caller's context. Probably the pagefault occurs at one of these locations.
Yet when i instantiate this class, I get the "no RM attachment" message, which results in this thread not executing at all. Does anyone know what is happening? Can parameters be passed to a thread via its constructor?
yes, that's the recommended way.
regards stefan
PS: most mail clients and archive software use the "In-Reply-To" mail header to structure related mails in "threads". If you start a topic with a different subject, it would be nice, if you would not reply to a former mail of the list ;-)
Peter
--- The Planet: dedicated and managed hosting, cloud storage, colocation Stay online with enterprise data centers and the best network in the business Choose flexible plans and management services without long-term contracts Personal 24x7 support from experience hosting pros just a phone call away. http://p.sf.net/sfu/theplanet-com _______________________________________________ Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
-- Stefan Kalkowski Genode Labs Developer http://genode-labs.com
The Planet: dedicated and managed hosting, cloud storage, colocation Stay online with enterprise data centers and the best network in the business Choose flexible plans and management services without long-term contracts Personal 24x7 support from experience hosting pros just a phone call away. http://p.sf.net/sfu/theplanet-com _______________________________________________ Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Peter,
So what i'm currently trying to do is that i'm trying to have a thread, whose purpose is to initialize some more genode threads as it results in the page faults for some reason. It seems that Genode doesn't like me creating and starting thread instances by another thread (ie. main creates thread1 -> thread1 creates thread2), which I find weird if in actual fact that this actually is not meant to work. I created and started an instance of thread2 in the main function of my genode server, which resulted in that thread working, whereas creating and starting an instance of thread2 in thread1 does not seem to work. I have a question that may contribute to me coming up with a workaround to this problem.
creating threads from other threads should work as expected. Your observation that thread creation from the main thread works but not from any another thread suggests that your creator thread has a too small stack. By default, the main thread has a pretty large stack (64K) but for custom created threads, the typical stack size supplied as template argument to the 'Thread' template is much smaller, in most cases 4K or 8K. So could you try increasing the stack size to 64K for your custom threads?
BTW, because this is a recurring problem, we currently investigate changing the stack allocation such that stack overflows can be easily detected and never corrupt data.
Given that a thread may call a function that belongs to another class, is there any way for me to obtain the ID of the thread that is currently executing? In previous builds of OKL4, L4_Myself() could be used within a function which would return the ID of the thread that was executing when the given function executes.
In OKL4 2.1 there is no such system call. However, Genode provides a way to do it anyway (using a special thread-bootstap protocol). By calling the static member function 'Thread_base::myself()', the caller can obtain its own 'Thread_base' object. This way, you can get the physical thread ID using the 'tid()' accessor. Or even better, you can cast the returned pointer to the specific thread class access the corresponding context.
However, in general, I recommend not relying on this thread-local storage (TLS) mechanism but rather pass the needed context as a pointer to the code that needs to access it. According to our experience, TLS is never needed when developing new code - you can always pass the context to functions as argument. Our solely reason to introduce 'myself()' was the need to reuse existing code (Linux driver, Qt), which already relied on TLS. That said, I'd like to encourage you to look again at your design to see if TLS is really a necessity. In my opinion, avoiding the use of TLS yields to much better code.
Norman
Hi,
I noticed that there isn't any support for printing floating point numbers. I was wondering whether someone has a patch of some sort that provides this functionality, even at a basic level.
Peter
Hi Peter,
I noticed that there isn't any support for printing floating point numbers. I was wondering whether someone has a patch of some sort that provides this functionality, even at a basic level.
the default printf functionality is pretty limited to keep the complexity of the base framework as low as possible. However, a complete printf implementation is provided by the libc. In the 'target.mk' file, you just need to specify:
LIBS += libc
Then you can include '<stdio.h>' and use 'printf' with all features as usual.
Norman
Hi,
So i've encountered problems with trying to use stdio.h. After adding libc to the build directory and the target.mk file, i keep getting errors with some of the libc header files relating to variables like va_list. On face value, it seems that libc and C++ don't like to play with each other...
Peter
On 01/02/2010, at 5:27 AM, Norman Feske wrote:
Hi Peter,
I noticed that there isn't any support for printing floating point numbers. I was wondering whether someone has a patch of some sort that provides this functionality, even at a basic level.
the default printf functionality is pretty limited to keep the complexity of the base framework as low as possible. However, a complete printf implementation is provided by the libc. In the 'target.mk' file, you just need to specify:
LIBS += libc
Then you can include '<stdio.h>' and use 'printf' with all features as usual.
Norman
The Planet: dedicated and managed hosting, cloud storage, colocation Stay online with enterprise data centers and the best network in the business Choose flexible plans and management services without long-term contracts Personal 24x7 support from experience hosting pros just a phone call away. http://p.sf.net/sfu/theplanet-com _______________________________________________ Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main