Getting tls symbols out of the compiler.

Johannes Pfau nospam at example.com
Thu May 30 01:25:48 PDT 2013


Am Thu, 30 May 2013 01:19:10 +0200
schrieb "Iain Buclaw" <ibuclaw at ubuntu.com>:

> OK, from today till the end of the week I'm going to be sitting 
> down and thinking through this, as I'd really like the emitting 
> of _tlsstart and _tlsend out of the compiler by hook or by crook.
> 
> 
> Phase one - start:
> 
> We have rt/tls.S.  Have added this to the libdruntime builds, and 
> I see no immediate problems running this through the testsuite  
> (though - that is never really a good indicator of anything).  
> Drawbacks, this is only available for linux at the moment. But 
> that's fine if we keep this temporary for the week.

Do you know what that comment in that file "Sadly, this does not work
because ld orders [...]" is about?

> Phase two - plan:
> 
> The GC has a hook gc_addRoot used for the purpose of tracking GC 
> allocated memory in C-land.  The idea I've got turning over in my 
> head at the moment is that any thread local decls that are 
> 'new-able' (classes, pointers, d arrays) are added as a root upon 
> 'new' declaration,  this is safe-guarded by a thread-local static 
> to prevent multiple calls to gc_addRoot.
> 

The good part part is that this will work with non-contiguous TLS, i.e
GCC emulated TLS. The bad part is that it'll be very slow so it should
really only be a fallback. And what about non-newable types?

Why don't we register all thread local variables in a module
constructor instead (in the C one or in the D one)?

static int a;
static void* b; 

static this()
{
    gc_addRoot(&a);
    gc_addRoot(&b);
}

Then unload in the module destructor. We could try to optimize that,
although we have to be careful:

static this() //pseudo code
{
    void*[2] roots;
    roots[0] = &a;
    roots[1] = &b;
    if(isContiguous(roots[])) //Sort. need to allow alignment though
       gc_addRange(roots[0], roots[$] + size) //probably need to keep a
       size array as well
    else
        foreach(ptr; roots)
              gc_addRoot(ptr);
}

This can detect if the TLS memory is contiguous and then only add one
range per module. Maybe it's not worth the effort as long as it's only
a slow fallback (and even with the optimization it'll still be slow)

> Though this should not be required if we have a proper TLS GC in 
> place.

Do you mean Martin Nowak's shared library/TLS work? That indeed sounds
like the proper solution.

(And maybe the D community should develop a sane standard interface to
the runtime linker to access sections. Then go lobbying all major libcs
out there...)


More information about the D.gnu mailing list