Thread overview
Windows specific: MS C++ versus D thread local variables
Nov 26, 2022
NonNull
Nov 28, 2022
NonNull
Nov 29, 2022
Gregor Mückl
November 26, 2022

Hello, a low level question about Windows internals and D interacting with .NET at a low level.

I just made an experimental native .lib (static library) with MS's C++ compiler, providing a C API for D to link to. The .lib contains one module compiled with the /CLR option which provides some functions manipulating .NET objects, and the C API is in another module compiled to native code (no /CLR option), containing the definitions of the functions to be exported to D, which in turn call those in the CLR module via a mechanism silently implemented by the MS compiler.

I then have successfully used both dmd and ldc2 to build a D test program statically linked to this .lib calling the functions in its API. It works fine in this toy singly threaded example. All builds are 64-bit. I am using the versions of the compilers that came with Visual D. As well as the C++ compiler that comes with VS2022 (Community).

In the CLR module I have a static variable that can contain a reference to a .NET object. I need that variable to be thread local. I achieved this by prefixing its declaration with [System::ThreadStaticAttribute]. But this is thread local for .NET concurrency. How will this variable behave with a multi-threaded D program (that calls those exported library functions from more than one thread) and why?

I first had written the library code for a .dll (dynamic library) and had the D test program be linked to its import library, so I could make it work without the inevitable linkage issues. How will the static variable behave in this situation with a multi-threaded D program and why? --- the same as when statically linked?

I'm looking for an actual technical explanation in both cases please.

November 28, 2022

On Saturday, 26 November 2022 at 23:36:13 UTC, NonNull wrote:

>

In the CLR module I have a static variable that can contain a reference to a .NET object. I need that variable to be thread local. I achieved this by prefixing its declaration with [System::ThreadStaticAttribute]. But this is thread local for .NET concurrency. How will this variable behave with a multi-threaded D program (that calls those exported library functions from more than one thread) and why?

I tested this with D threads and it works for my test program. I might guess that this is so in general, because such a library has to successfully work with arbitrary MS VC++ and that "interop" is defined by MS to work.

November 29, 2022

On Monday, 28 November 2022 at 18:51:37 UTC, NonNull wrote:

>

I tested this with D threads and it works for my test program. I might guess that this is so in general, because such a library has to successfully work with arbitrary MS VC++ and that "interop" is defined by MS to work.

I worked on products where native C++ threads were calling complex CLR code and we never had an issue with the CLR runtime in these scenarios. As far as I recall the .Net documentation, this is entirely supported. I believe that the shim code handling the transitions behind the scenes takes care of that. If you want to know how it works in detail, I guess you have to dig into the runtime sources. They are complex and hard to understand, though.