On Friday, 14 July 2017 at 09:13:26 UTC, Johannes Pfau wrote:
Another solution could be to enhance libgcc emutls to allow
custom allocators, then have a special allocation function in
druntime for all D emutls variables. As far as I know there is
no GC heap that is scanned, but not automatically collected?
I believe that's what's done with the TLS ranges now, they're
scanned but not collected, though they're not part of the GC heap.
I'd need a way to completely manually manage GC.malloc/GC.free
memory without the GC collecting this memory, but still
scanning this memory for pointers. Does something like this
exist?
It doesn't have to be GC.malloc/GC.free, right? The current
DMD-style emutls simply mallocs and frees the TLS data itself and
only expects the GC to scan it.
Another option is simply using the DMD-style emutls. But as far
as I can see the DMD implementation never supported dynamic
loading of shared libraries? This is something the GCC emutls
support is quite good at: It doesn't have any platform
dependencies (apart from mutexes and some way to store one
thread specific pointer+destructor) and should work with all
kinds of shared library combinations. DMD style emutls also
does not allow sharing TLS variables between D and other
languages.
Yes, DMD's emutls was never made to work with loading multiple
shared libraries. As for sharing with other languages without
copying the TLS data over, that seems a rare scenario.
So I was thinking, if DMD style emutls really doesn't support
shared libraries, maybe we should just clone a GCC-style,
compiler and OS agnostic emutls implementation into druntime? A
D implementation could simply allocate all internal arrays
using the GC. This should be just as efficient as the C
implementation for variable access and interfacing to the GC is
trivial. It gets somewhat more complicated if we want to use
this in betterC though. We also lose C/C++ compatibility though
by using such a custom implementation.
It would be a good alternative to have, and you're not going to
care in betterC mode, since there's no druntime or GC. You'd
have to be careful how you called TLS data from C/C++, but it
could still be done.
The rest of this post is a description of the GCC emutls code.
Someone
can use this specification to implement a clean-room design D
emutls
clone.
Source code can be found here, but beware of the GPL license:
https://github.com/gcc-mirror/gcc/blob/master/libgcc/emutls.c
[...]
There is also this llvm implementation, available under
permissive licenses and actually documented somewhat:
https://github.com/llvm-mirror/compiler-rt/blob/master/lib/builtins/emutls.c