On 2012-03-19 09:15, Johannes Pfau wrote:
Am Sun, 18 Mar 2012 21:57:57 +0100
schrieb Jacob Carlborg<d...@me.com>:

On 2012-03-18 12:32, Johannes Pfau wrote:
I thought about supporting emulated tls a little. The GCC emutls.c
implementation currently can't work with the gc, as every TLS
variable is allocated individually and therefore we don't have a
contiguous memory region for the gc. I think these are the possible
solutions:

Why not use the native TLS implementation when available and roll our
own, like DMD on Mac OS X, when none exists?

That's what we (mostly) do right now. We have 2 issues:

* Our own, emulated TLS support is implemented in GCC. This means it's
   also used in C, which is great. Also GCC's emulated tls needs
   absolutely no special features in the runtime linker, compile time
   linker or language frontends. It's very portable and works with all
   weird combinations of dynamic libraries, dlopen, etc.
   But it has one quirk: It doesn't allocate TLS memory in a contiguous
   way, every tls variable is allocated using malloc. This means we
   can't pass a range to the GC for the tls variables. So we can't
   support this emutls in the GC.

Ok, I see.

* The other issue with native TLS is that using bracketing with
   __tls_beg and __tls_end has corner cases where it doesn't work. We'd
   need an alternative to locate the TLS memory addresses and TLS sizes.
   But there's no standard or public API to do that.

On Mac OS X they are actually not needed. Don't know about other platforms.

BTW, I think it would be possible to emulate TLS in a very similar
way to how it's implemented natively for ELF.


I don't think it's that easy. For example, how would you assign module
ids? For native TLS this is partially done by the compile time linker
(for the main application and libraries that are always loaded), but if
no native TLS is available, we can't rely on the linker to do that. We
also need some way to get the current module id in running code.

As I understand it, in the native ELF implementation, assembly is used to access the current module id, this is for FreeBSD:

http://people.freebsd.org/~marcel/tls.html

This is how ___tls_get_addr is implemented on FreeBSD ELF i386:

https://bitbucket.org/freebsd/freebsd-head/src/4e8f50fe2f05/libexec/rtld-elf/i386/reloc.c#cl-355

And how do we get the TLS initialization data? If we placed it into an
array, like DMD does on OSX, we could use dlsym for dlopened libraries,
but what about initially loaded libraries?

In the same way it's done in the native implementation. Isn't it possible to access all loaded libraries?

Say you have application 'app', which depends on 'liba' and 'libb'. All
of these have TLS data. Maybe we could implement something using
dl_iterate_phdr, but that's a nonstandard extension.

Ok. Mac OS X has this a function called "_dyld_register_func_for_add_image", I guess other OS'es don't have a corresponding function? In general all this stuff very low level and nonstandard.

https://developer.apple.com/library/mac/#documentation/developertools/Reference/MachOReference/Reference/reference.html#jumpTo_53

Compare that to GCC's emulation, which is probably slow, but 'just
works' everywhere (except for the GC :-( ).

Yeah, that's a big advantage.

In general I was hoping that the work done by the dynamic loader to setup TLS could be moved to druntime.

--
/Jacob Carlborg

Reply via email to