Jump to page: 1 24  
Page
Thread overview
TLS for Android
Mar 08, 2014
Joakim
Mar 08, 2014
Jacob Carlborg
Mar 08, 2014
David Nadlinger
Mar 08, 2014
Joakim
Mar 08, 2014
David Nadlinger
Mar 09, 2014
Joakim
Mar 09, 2014
Joakim
Mar 09, 2014
David Nadlinger
Mar 09, 2014
Joakim
Mar 17, 2014
Joakim
Mar 20, 2014
Joakim
Re: TLS for Android (and iOS)
Mar 27, 2014
Dan Olson
Mar 27, 2014
Joakim
Mar 30, 2014
Dan Olson
Mar 30, 2014
Joakim
Mar 30, 2014
Dan Olson
Mar 30, 2014
Joakim
Mar 30, 2014
Dan Olson
Mar 30, 2014
Jacob Carlborg
Mar 30, 2014
Dan Olson
Mar 31, 2014
Jacob Carlborg
Mar 31, 2014
David Nadlinger
Mar 31, 2014
Dan Olson
Apr 01, 2014
Dan Olson
Mar 31, 2014
Jacob Carlborg
Mar 31, 2014
David Nadlinger
Mar 31, 2014
Jacob Carlborg
Mar 31, 2014
Dan Olson
Mar 31, 2014
David Nadlinger
Mar 31, 2014
Jacob Carlborg
Mar 27, 2014
David Nadlinger
Mar 08, 2014
Dan Olson
Mar 08, 2014
David Nadlinger
Mar 08, 2014
Dan Olson
Mar 09, 2014
Joakim
Mar 09, 2014
Jacob Carlborg
Mar 09, 2014
Joakim
Mar 09, 2014
Jacob Carlborg
March 08, 2014
So I've been looking into implementing TLS for Android/x86, rummaging through old TLS git commits for dmd and ldc to see what to do.  It appears that Walter implemented TLS on OS X more than four years ago by packing thread-local variables into special segments and then unpacking them in druntime, which uses pthread_(get|set)specific on OS X nowadays:

http://www.drdobbs.com/architecture-and-design/implementing-thread-local-storage-on-os/228701185
https://github.com/D-Programming-Language/druntime/blob/master/src/rt/sections_osx.d#L106

Since Android also provides these pthread functions for TLS, seems like a similar approach is called for.

I notice that ldc never used this approach, depending on llvm's built-in TLS support instead:

https://github.com/ldc-developers/ldc/commit/4d7a6eda234bc8d12703cc577c09c2ca50ac6bda#diff-19

It seems that this also meant that TLS wasn't garbage-collected on OSX, until David added it a little more than a year ago:

https://github.com/ldc-developers/druntime/blob/ldc/src/ldc/osx_tls.c

I can copy what dmd is doing on OS X Mach-O with ELF, but it's not going to be easily transferable to ldc, which will be necessary for Android/ARM.

Do you have any advice on how to pull this off with ldc?  Should I be going the dmd route and packing the TLS myself?  Does llvm provide good support for this?

Or is there some other llvm TLS shortcut I can use?  I tried to see if llvm just has some thread-local implementation that automatically uses pthread_setspecific, but didn't find anything.
March 08, 2014
On 2014-03-08 01:55, Joakim wrote:
> So I've been looking into implementing TLS for Android/x86, rummaging
> through old TLS git commits for dmd and ldc to see what to do.  It
> appears that Walter implemented TLS on OS X more than four years ago by
> packing thread-local variables into special segments and then unpacking
> them in druntime, which uses pthread_(get|set)specific on OS X nowadays:
>
> http://www.drdobbs.com/architecture-and-design/implementing-thread-local-storage-on-os/228701185
>
> https://github.com/D-Programming-Language/druntime/blob/master/src/rt/sections_osx.d#L106
>
>
> Since Android also provides these pthread functions for TLS, seems like
> a similar approach is called for.
>
> I notice that ldc never used this approach, depending on llvm's built-in
> TLS support instead:
>
> https://github.com/ldc-developers/ldc/commit/4d7a6eda234bc8d12703cc577c09c2ca50ac6bda#diff-19

Yes. DMD started to implemented support for TLS on OS X before 10.7 which is the first version of OS X to natively support TLS. LDC doesn't support older versions of OS X than 10.7 since it uses native TLS.

-- 
/Jacob Carlborg
March 08, 2014
On 03/08/2014 01:55 AM, Joakim wrote:
> Do you have any advice on how to pull this off with ldc?  Should I be
> going the dmd route and packing the TLS myself?  Does llvm provide good
> support for this?
>
> Or is there some other llvm TLS shortcut I can use?  I tried to see if
> llvm just has some thread-local implementation that automatically uses
> pthread_setspecific, but didn't find anything.

LLVM does support putting variables into custom sections, and you can more or less get away with the DMD bracketing approach (see e.g. the new ModuleInfo discovery functionality I implemented for Linux, which is the same as DMD's druntime uses). However, there is a catch: Due to what I can only imagine is a bug, LLVM does not support emitting a symbol both into a custom section and with weak linkage. Thus, you might be in for a round of LLVM hacking either way, even though it will likely involve much less when going the DMD route.

However, there is a third options which might be worth investigating, namely re-implementing at least parts of the necessary runtime linker features in druntime and continuing to use the same scheme as on GNU Linux/x86. This depends on %gs not being used in another way, etc. though.

David
March 08, 2014
On Saturday, 8 March 2014 at 14:25:43 UTC, David Nadlinger wrote:
> LLVM does support putting variables into custom sections, and you can more or less get away with the DMD bracketing approach (see e.g. the new ModuleInfo discovery functionality I implemented for Linux, which is the same as DMD's druntime uses).
You're talking about findDataSection and friends?

https://github.com/ldc-developers/druntime/blob/ldc/src/rt/sections_ldc.d#L115

> However, there is a catch: Due to what I can only imagine is a bug, LLVM does not support emitting a symbol both into a custom section and with weak linkage. Thus, you might be in for a round of LLVM hacking either way, even though it will likely involve much less when going the DMD route.
Hmm, I guess this is why you don't use the bracketing approach anywhere?  What will be much less when going the DMD route?

> However, there is a third options which might be worth investigating, namely re-implementing at least parts of the necessary runtime linker features in druntime and continuing to use the same scheme as on GNU Linux/x86. This depends on %gs not being used in another way, etc. though.
I tried to reuse the existing dl_iterate_phdr approach on Android, but then I noticed that the dl_phdr_info struct defined in bionic doesn't include the dlpi_tls_modid and dlpi_tls_data members.  However, now that you mention it, maybe those aren't strictly necessary, as long as I'm not worried about shared libraries.  I'll look into it further.

As for reimplementing the runtime linker, in a sense that's what's being done with dmd/druntime for OS X, where it implements it's own ___tls_get_addr using pthread_setspecific.  I'll have to do the same for Android, as bionic doesn't have a __tls_get_addr.
March 08, 2014
David Nadlinger <code@klickverbot.at> writes:

> On 03/08/2014 01:55 AM, Joakim wrote:
>> Do you have any advice on how to pull this off with ldc?  Should I be going the dmd route and packing the TLS myself?  Does llvm provide good support for this?
>>
>> Or is there some other llvm TLS shortcut I can use?  I tried to see if llvm just has some thread-local implementation that automatically uses pthread_setspecific, but didn't find anything.
>
> LLVM does support putting variables into custom sections, and you can more or less get away with the DMD bracketing approach (see e.g. the new ModuleInfo discovery functionality I implemented for Linux, which is the same as DMD's druntime uses). However, there is a catch: Due to what I can only imagine is a bug, LLVM does not support emitting a symbol both into a custom section and with weak linkage. Thus, you might be in for a round of LLVM hacking either way, even though it will likely involve much less when going the DMD route.
>
> However, there is a third options which might be worth investigating,
> namely re-implementing at least parts of the necessary runtime linker
> features in druntime and continuing to use the same scheme as on GNU
> Linux/x86. This depends on %gs not being used in another way,
> etc. though.
>
> David

While on the subject of TLS, that is probably the most needed language feature to allow threading to work reliably on iOS.  So hoping the solution will work on iOS too!

Another topic - I was looking at adding fiber_switchContext support for arm in threadasm.S, and noticed GDC's version has an arm implementation.  Is it ok to use portions of GDC source in LDC?
-- 
Dan

March 08, 2014
On Sat, Mar 8, 2014 at 8:11 PM, Dan Olson <zans.is.for.cans@yahoo.com> wrote:
> Another topic - I was looking at adding fiber_switchContext support for arm in threadasm.S, and noticed GDC's version has an arm implementation.  Is it ok to use portions of GDC source in LDC?

If their code is Boost-licensed (general druntime/Phobos license), yes.

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

> On Sat, Mar 8, 2014 at 8:11 PM, Dan Olson <zans.is.for.cans@yahoo.com> wrote:
>> Another topic - I was looking at adding fiber_switchContext support for arm in threadasm.S, and noticed GDC's version has an arm implementation.  Is it ok to use portions of GDC source in LDC?
>
> If their code is Boost-licensed (general druntime/Phobos license), yes.
>
> David

Yes, that file is Boost - good!
March 08, 2014
On Sat, Mar 8, 2014 at 7:16 PM, Joakim <joakim@airpost.net> wrote:
> On Saturday, 8 March 2014 at 14:25:43 UTC, David Nadlinger wrote:
>>
>> LLVM does support putting variables into custom sections, and you can more or less get away with the DMD bracketing approach (see e.g. the new ModuleInfo discovery functionality I implemented for Linux, which is the same as DMD's druntime uses).
>
> You're talking about findDataSection and friends?
>
> https://github.com/ldc-developers/druntime/blob/ldc/src/rt/sections_ldc.d#L115

Not quite. I was referring to
https://github.com/ldc-developers/druntime/blob/ldc-merge-2.064/src/rt/sections_linux.d
(_d_dso_registry, ...) and the associated compiler-side
implementation,
https://github.com/ldc-developers/ldc/blob/5b14a5e5c4f292024afd8e5f520e837035942003/gen/module.cpp#L396.

>> However, there is a catch: Due to what I can only imagine is a bug, LLVM does not support emitting a symbol both into a custom section and with weak linkage. Thus, you might be in for a round of LLVM hacking either way, even though it will likely involve much less when going the DMD route.
>
> Hmm, I guess this is why you don't use the bracketing approach anywhere? What will be much less when going the DMD route?

Actually, we didn't use the special section approach at all until very recently (i.e. Martin's shared library changes in 2.064). And I meant that you would probably get away with less LLVM hacking when just changing the way LDC emits TLS globals/accesses than when implementing "emulated" TLS on the LLVM backend side.

> As for reimplementing the runtime linker, in a sense that's what's being done with dmd/druntime for OS X, where it implements it's own ___tls_get_addr using pthread_setspecific.  I'll have to do the same for Android, as bionic doesn't have a __tls_get_addr.

Well, yes and no. I was specifically referring to keeping the normal TLS infrastructure (i.e. %gs-based addressing on Linux/x86) in place and just replacing the part that Glibc does (but Bionic doesn't) with a piece of code in druntime. __tls_get_addr isn't necessarily used on x86.

David
March 09, 2014
On Saturday, 8 March 2014 at 22:44:16 UTC, David Nadlinger wrote:
> On Sat, Mar 8, 2014 at 7:16 PM, Joakim <joakim@airpost.net> wrote:
>> On Saturday, 8 March 2014 at 14:25:43 UTC, David Nadlinger wrote:
>>>
>>> LLVM does support putting variables into custom sections, and you can more
>>> or less get away with the DMD bracketing approach (see e.g. the new
>>> ModuleInfo discovery functionality I implemented for Linux, which is the
>>> same as DMD's druntime uses).
>>
>> You're talking about findDataSection and friends?
>>
>> https://github.com/ldc-developers/druntime/blob/ldc/src/rt/sections_ldc.d#L115
>
> Not quite. I was referring to
> https://github.com/ldc-developers/druntime/blob/ldc-merge-2.064/src/rt/sections_linux.d
> (_d_dso_registry, ...) and the associated compiler-side
> implementation,
> https://github.com/ldc-developers/ldc/blob/5b14a5e5c4f292024afd8e5f520e837035942003/gen/module.cpp#L396.

Okay, I started looking around the master branch and didn't find what you were talking about.  No wonder, it's in the merge-2.064 branch.  I'll look at what you did there.

>>> However, there is a catch: Due to what I can only imagine is a bug, LLVM
>>> does not support emitting a symbol both into a custom section and with weak
>>> linkage. Thus, you might be in for a round of LLVM hacking either way, even
>>> though it will likely involve much less when going the DMD route.
>>
>> Hmm, I guess this is why you don't use the bracketing approach anywhere?
>> What will be much less when going the DMD route?
>
> Actually, we didn't use the special section approach at all until very
> recently (i.e. Martin's shared library changes in 2.064). And I meant
> that you would probably get away with less LLVM hacking when just
> changing the way LDC emits TLS globals/accesses than when implementing
> "emulated" TLS on the LLVM backend side.

Well, the special section approach still isn't in the master branch, hence my confusion.  Okay, I wasn't clear that you were comparing the dmd route to having llvm generate the right pthread calls for Android.

>> As for reimplementing the runtime linker, in a sense that's what's being
>> done with dmd/druntime for OS X, where it implements it's own
>> ___tls_get_addr using pthread_setspecific.  I'll have to do the same for
>> Android, as bionic doesn't have a __tls_get_addr.
>
> Well, yes and no. I was specifically referring to keeping the normal
> TLS infrastructure (i.e. %gs-based addressing on Linux/x86) in place
> and just replacing the part that Glibc does (but Bionic doesn't) with
> a piece of code in druntime. __tls_get_addr isn't necessarily used on
> x86.

While Android/X86 TLS does use the %gs register (https://github.com/android/platform_bionic/blob/master/libc/private/__get_tls.h#L45), that's not portable and I'd like to try Android/ARM after this, so I'll stick with the pthread_(get|set)specific calls to wrap it:

https://github.com/android/platform_bionic/blob/master/libc/bionic/pthread_key.cpp
March 09, 2014
On Saturday, 8 March 2014 at 19:11:52 UTC, Dan Olson wrote:
> While on the subject of TLS, that is probably the most needed language
> feature to allow threading to work reliably on iOS.  So hoping the
> solution will work on iOS too!

I wondered earlier why you weren't just using Walter's packed TLS approach and now I see why, ldc doesn't use it.  Looks like Apple hasn't ported the TLV functions which ldc uses to iOS yet either, so you're out of luck there too.  I guess you'll have to port Walter's approach to ldc to get TLS working on iOS:

https://github.com/D-Programming-Language/dmd/blob/master/src/backend/machobj.c#L1673

Either that or get llvm to emit the right pthread calls, like I mentioned earlier.
« First   ‹ Prev
1 2 3 4