Initializing D runtime and executing module and TLS ctors for D libraries

IGotD- nise at nise.com
Sun Jan 24 10:28:43 UTC 2021


On Sunday, 24 January 2021 at 03:59:26 UTC, Ali Çehreli wrote:
>
> That must be the case for threads started by D runtime, right? 
> It sounds like I must call rt_moduleTlsCtor explicitly for 
> foreign threads. It's still not clear to me which modules' TLS 
> variables are initialized (copied over). Only this module's or 
> all modules that are in the program? I don't know whether it's 
> possible to initialize one module; rt_moduleTlsCtor does not 
> take any parameter.
>

Any threads started by druntime has proper initialization of 
course. Any thread started by any module written in another 
language will not do D the thread initialization.

All TLS variables in all loaded modules are being initialized 
(only copying and zeoring) by the OS system code for each thread 
that the OS system knows about. After that it is up to each 
library for each language to do further initialization. Next time 
__tls_get_addr is being called after loading a library, the TLS 
variables of any new module will be found and initialized.

It is a mystery to me why the TLS standard never included a 
ctor/dtor vector for TLS variables. It is in practice possible 
but they didn't do it. The whole TLS design is like a swiss 
scheese.

>
> Did you mean a generic API, which makes calls to D? That's how 
> I have it: an extern(C) API function calling proper D code.
>

I have a lot of system code written in C++ which also include 
callbacks from that code. In order to support D a layer is 
necessary to catch all callbacks in a trampoline and invoke D 
delegates. Calling D code directly with extern(C) should be 
avoided because 1. D delegates are so much more versatile. 2. You 
must use a trampoline in order to do D specific thread 
initialization anyway. Since std::function cannot be used in a 
generic interface I actually use something like this, 
http://blog.coldflake.com/posts/C++-delegates-on-steroids/. Which 
is more versatile than plain extern(C) but simple enough so that 
it can be used by any language. In the case of D the "this 
pointer" can be used to a pointer of a D delegate.

Creating language agnostic interfaces require more attention than 
usual as I have experienced. Strings for example complicates 
things further as they are different for every language.



More information about the Digitalmars-d-learn mailing list