Hello,
Quick question: I am using Genode+Fiasco.OC, and I am trying to access the TLS of a particular thread. How can that be done? Where could I find an example on this?
Thanks!
Amadeo
Hello Amadeo,
Quick question: I am using Genode+Fiasco.OC, and I am trying to access the TLS of a particular thread. How can that be done? Where could I find an example on this?
in general, I advise against using TLS when crafting new code. Throughout Genode, we use to pass all context information needed by each thread explicitly via function arguments. This way, the behaviour of the code becomes more obvious. TLS is probably the worst of all side effects of C++ programs because it actually bypasses the language.
The Genode approach to attach thread-local information to a thread is inheriting the 'Thread' class template and adding additional context information as member variables to the custom 'Thread' class. The 'entry' function of the 'Thread' as well as all other member functions can then access these thread-local member variables in a natural way.
Because of our stance regarding TLS, Genode was intentionally lacking a generic TLS feature until one year ago. However, while porting existing code (i.e., Linux device drivers, lwIP, and Qt4), we encountered the need to provide TLS support. It comes in the form of the static function 'Thread_base::myself()'. This function returns the 'Thread_base' pointer of the calling thread (or 0 if the called by the main thread). The returned pointer can be used either
* As a key into a custom TLS data structure (e.g., using an AVL tree). This approach is used by our Qt4 port and the DDE Kit (for example, see: 'os/src/lib/dde_kit/thread.h' and 'os/src/lib/dde_kit/thread.cc')
* To obtain a pointer of a known thread type derived from 'Genode::Thread_base' via a 'static_cast' or 'dynamic_cast'
My_thread = static_cast<My_thread *>(Thread_base::myself());
Obviously, using the static cast is faster than the lookup described above. It is feasible if all TLS-using threads are custom threads (i.e., not a 'Server_activation'). Using a dynamic cast is useful if this condition cannot be asserted.
Finally, you can of course use kernel-specific functionality to provide TLS in an architecture-dependent way (e.g., using segment registers on x86 as supported by Fiasco.OC). However, this code becomes unportable with regard to other kernels and other CPU architectures. Unless the TLS-using code must be highly optimized for performance, I would avoid this approach.
If you are developing new code, I'd like to suggest to reconsider the using TLS. Our experience tells us not only that it is entirely possible to live without this feature, but also that non-TLS-using code is much more enjoyable to use and maintain.
Best regards Norman
That makes total sense. Thanks Norman for your help!
Amadeo
-----Original Message----- From: Norman Feske [mailto:norman.feske@...1...] Sent: Tuesday, March 08, 2011 10:27 AM To: genode-main@lists.sourceforge.net Subject: Re: TLS in Genode+Fiasco.OC
Hello Amadeo,
Quick question: I am using Genode+Fiasco.OC, and I am trying to access the TLS of a particular thread. How can that be done? Where could I find an example on this?
in general, I advise against using TLS when crafting new code. Throughout Genode, we use to pass all context information needed by each thread explicitly via function arguments. This way, the behaviour of the code becomes more obvious. TLS is probably the worst of all side effects of C++ programs because it actually bypasses the language.
The Genode approach to attach thread-local information to a thread is inheriting the 'Thread' class template and adding additional context information as member variables to the custom 'Thread' class. The 'entry' function of the 'Thread' as well as all other member functions can then access these thread-local member variables in a natural way.
Because of our stance regarding TLS, Genode was intentionally lacking a generic TLS feature until one year ago. However, while porting existing code (i.e., Linux device drivers, lwIP, and Qt4), we encountered the need to provide TLS support. It comes in the form of the static function 'Thread_base::myself()'. This function returns the 'Thread_base' pointer of the calling thread (or 0 if the called by the main thread). The returned pointer can be used either
* As a key into a custom TLS data structure (e.g., using an AVL tree). This approach is used by our Qt4 port and the DDE Kit (for example, see: 'os/src/lib/dde_kit/thread.h' and 'os/src/lib/dde_kit/thread.cc')
* To obtain a pointer of a known thread type derived from 'Genode::Thread_base' via a 'static_cast' or 'dynamic_cast'
My_thread = static_cast<My_thread *>(Thread_base::myself());
Obviously, using the static cast is faster than the lookup described above. It is feasible if all TLS-using threads are custom threads (i.e., not a 'Server_activation'). Using a dynamic cast is useful if this condition cannot be asserted.
Finally, you can of course use kernel-specific functionality to provide TLS in an architecture-dependent way (e.g., using segment registers on x86 as supported by Fiasco.OC). However, this code becomes unportable with regard to other kernels and other CPU architectures. Unless the TLS-using code must be highly optimized for performance, I would avoid this approach.
If you are developing new code, I'd like to suggest to reconsider the using TLS. Our experience tells us not only that it is entirely possible to live without this feature, but also that non-TLS-using code is much more enjoyable to use and maintain.
Best regards Norman