March 31, 2014 Re: TLS for Android (and iOS) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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 Re: TLS for Android (and iOS) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dan Olson | 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 Re: TLS for Android (and iOS) | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | "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 Re: TLS for Android (and iOS) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dan Olson | 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 Re: TLS for Android (and iOS) | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | 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 Re: TLS for Android (and iOS) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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 Re: TLS for Android (and iOS) | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | 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 Re: TLS for Android (and iOS) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dan Olson | 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 |
Copyright © 1999-2021 by the D Language Foundation