March 31, 2014
Jacob Carlborg <doob@me.com> writes:

> Regardless of the license, you can still give a try to see if the technical parts work.

I have tried and success.

I added threadLocalHelpers.s and threadLocalVariables.c, modified to enable for arm, then had to sprinkle in some missing types from dl_priv.h.  Then put in a call to tlv_initializer().

The proof is that thread locals get proper initial values when accessed through tlv_get_addr().  For example, a thread local double is being initialized to nan.

Still having LLVM emit a __tls_get_addr, so to try this out, I changed
my test __tls_get_addr() implementation to forward to tlv_get_addr() in
threadLocalHelpers.s.

    extern (C)
    void* __tls_get_addr(TLVDescriptor* tlvd)
    {
        __gshared static ubyte data[512];

        printf("__tls_get_addr %p \n", tlvd);
        printf("thunk %p, key %u, offset %u\n",
               tlvd.thunk, tlvd.key, tlvd.offset);

        // tlv_initializer() will change thunk to tlv_get_addr
        if (tlvd.thunk is &tlv_get_addr) {
            puts("calling real tlv_get_addr instead");
            return tlv_get_addr(tlvd);
        }

        // tlv not initialized yet, return my fake thread local data.
        return data.tlvd + tlvd.offset;
    }
March 31, 2014
On 31 Mar 2014, at 17:23, Dan Olson wrote:
> I added threadLocalHelpers.s and threadLocalVariables.c, modified to enable for arm, then had to sprinkle in some missing types from dl_priv.h.  Then put in a call to tlv_initializer().
>
> The proof is that thread locals get proper initial values when accessed through tlv_get_addr().  For example, a thread local double is being initialized to nan.

Nice!

David
March 31, 2014
"David Nadlinger" <code@klickverbot.at> writes:

> On 31 Mar 2014, at 8:25, Jacob Carlborg wrote:
>> You'll just need to add a call to druntime in one of the functions in the dyld TLS code. Have a look at:
>>
>> https://github.com/D-Programming-Language/druntime/blob/master/src/rt/sections_osx.d
>
> More specifically, for the DMD TLS emulation implementation, this is
> done in the initTLSRanges() function, which forwards to
> getTLSBlock(). IIRC, initTLSRanges() is only called for new
> threads. For the main thread, the TLS ranges is included in the GC
> ranges detected in initSections().
>
> For LDC on OS X, which makes use of the 10.7+ system-level TLS
> implementation, the place where this is handled is
> https://github.com/ldc-developers/druntime/blob/a08f158618eb5d06c42bd4746b782312e937f6b3/src/rt/sections_ldc.d#L296. _d_dyld_getTLSRange
> uses an undocumented dyld API function (dyld_enumerate_tlv_storage) to
> get the actual TLS  memory range on the current thread:
> https://github.com/ldc-developers/druntime/blob/a08f158618eb5d06c42bd4746b782312e937f6b3/src/ldc/osx_tls.c.
>
> David

I had disabled initTLSRanges for iOS since dyld_enumerate_tlv_storage is
a stub for x86 (see
http://www.opensource.apple.com/source/dyld/dyld-210.2.3/src/threadLocalVariables.c).

Now that I have tweaked threadLocalVariables.c, dyld_enumerate_tlv_storage should now work on iOS. I will have to reenble initTLSRanges and see what happens.
-- 
Dan
March 31, 2014
On 2014-03-31 17:23, Dan Olson wrote:

> I have tried and success.
>
> I added threadLocalHelpers.s and threadLocalVariables.c, modified to
> enable for arm, then had to sprinkle in some missing types from
> dl_priv.h.  Then put in a call to tlv_initializer().
>
> The proof is that thread locals get proper initial values when accessed
> through tlv_get_addr().  For example, a thread local double is being
> initialized to nan.

Awesome :)

-- 
/Jacob Carlborg
March 31, 2014
On 2014-03-31 16:05, David Nadlinger wrote:

> For LDC on OS X, which makes use of the 10.7+ system-level TLS
> implementation, the place where this is handled is
> https://github.com/ldc-developers/druntime/blob/a08f158618eb5d06c42bd4746b782312e937f6b3/src/rt/sections_ldc.d#L296.
> _d_dyld_getTLSRange uses an undocumented dyld API function
> (dyld_enumerate_tlv_storage) to get the actual TLS  memory range on the
> current thread:
> https://github.com/ldc-developers/druntime/blob/a08f158618eb5d06c42bd4746b782312e937f6b3/src/ldc/osx_tls.c.

"dyld_enumerate_tlv_storage" should probably be replaced with a function that is publicly available, at some point.

-- 
/Jacob Carlborg
March 31, 2014
On 31 Mar 2014, at 19:39, Jacob Carlborg wrote:
> "dyld_enumerate_tlv_storage" should probably be replaced with a function that is publicly available, at some point.

If you find such a function, please let me know (or, better, submit a pull request).

Maybe it is possible to reimplement dyld_enumerate_tlv_storage using public APIs, but back then I didn't spend too much time on investigating that.

David
March 31, 2014
On 2014-03-31 19:42, David Nadlinger wrote:

> If you find such a function, please let me know (or, better, submit a
> pull request).

Hmm, it might be a bit more complicated than I first thought. I might have a look at it some time.

> Maybe it is possible to reimplement dyld_enumerate_tlv_storage using
> public APIs, but back then I didn't spend too much time on investigating
> that.

Fair enough.

-- 
/Jacob Carlborg
April 01, 2014
Dan Olson <zans.is.for.cans@yahoo.com> writes:

> "David Nadlinger" <code@klickverbot.at> writes:
>
>> On 31 Mar 2014, at 8:25, Jacob Carlborg wrote:
>>> You'll just need to add a call to druntime in one of the functions in the dyld TLS code. Have a look at:
>>>
>>> https://github.com/D-Programming-Language/druntime/blob/master/src/rt/sections_osx.d
>>
>> More specifically, for the DMD TLS emulation implementation, this is
>> done in the initTLSRanges() function, which forwards to
>> getTLSBlock(). IIRC, initTLSRanges() is only called for new
>> threads. For the main thread, the TLS ranges is included in the GC
>> ranges detected in initSections().
>>
>> For LDC on OS X, which makes use of the 10.7+ system-level TLS
>> implementation, the place where this is handled is
>> https://github.com/ldc-developers/druntime/blob/a08f158618eb5d06c42bd4746b782312e937f6b3/src/rt/sections_ldc.d#L296. _d_dyld_getTLSRange
>> uses an undocumented dyld API function (dyld_enumerate_tlv_storage) to
>> get the actual TLS  memory range on the current thread:
>> https://github.com/ldc-developers/druntime/blob/a08f158618eb5d06c42bd4746b782312e937f6b3/src/ldc/osx_tls.c.
>>
>> David
>
> I had disabled initTLSRanges for iOS since dyld_enumerate_tlv_storage is
> a stub for x86 (see
> http://www.opensource.apple.com/source/dyld/dyld-210.2.3/src/threadLocalVariables.c).

I meant it is a stub for ARM.

> Now that I have tweaked threadLocalVariables.c, dyld_enumerate_tlv_storage should now work on iOS. I will have to reenble initTLSRanges and see what happens.

I did reenable and it works.  I can tell because the std.datetime unittest uses enough memory that it causes a GC.  When I first rebuild everything with TLS enabled and plugged in support from threadLocalVariables.c (but without initTLSRanges enabled), the std.datetime unittest started crashing.  The datetime unittest tests have a fair number of thread locals.  Then I reenabled David's initTLSRanges() for iOS, and std.datetime unittest went back to passing.
-- 
Dan
1 2 3 4
Next ›   Last »