Jump to page: 1 2
Thread overview
October 13
Hi!

Can anyone explain what "--emulated-tls" actually do?

It solves my problem with correct static variables placement on ARM Cortex M3, but I don't know why.

October 13
On Tuesday, 13 October 2020 at 09:32:07 UTC, Denis Feklushkin wrote:
> Hi!
>
> Can anyone explain what "--emulated-tls" actually do?
>
> It solves my problem with correct static variables placement on ARM Cortex M3, but I don't know why.

Problem was:

Without --emulated-tls static member variables sometimes(?) was placed on same place. This not affect usual (TLS) variables, or shared/__gshared.

October 13
On Tuesday, 13 October 2020 at 09:59:40 UTC, Denis Feklushkin wrote:
> On Tuesday, 13 October 2020 at 09:32:07 UTC, Denis Feklushkin wrote:
>> Hi!
>>
>> Can anyone explain what "--emulated-tls" actually do?
>>
>> It solves my problem with correct static variables placement on ARM Cortex M3, but I don't know why.
>
> Problem was:
>
> Without --emulated-tls static member variables sometimes(?) was placed on same place.

I.e., compiler presumes that.


October 13
On Tuesday, 13 October 2020 at 09:32:07 UTC, Denis Feklushkin wrote:
> Hi!
>
> Can anyone explain what "--emulated-tls" actually do?
>
> It solves my problem with correct static variables placement on ARM Cortex M3, but I don't know why.

I think it is a compatibility layer that GCC provides. Instead of implementing everything yourself from scratch, GCC provide a framework and a set of hooks you should implement.

http://www.chiark.greenend.org.uk/doc/gcc-4.9-doc/gccint.html#Emulated-TLS

It seems like GCC provides default hooks, so for example if threading is not enabled this TLS emulation layer is probably pretty stupid and do not know what a thread is. The variables are dynamically allocated using the C library memory allocation functions.

In practice you should read about the Runtime ABI for the ARM architecture, how TLS is implemented for ARM. For a custom system you have all the degrees of freedom and can do what you want and is usually better. ARM and GCC also offers several options how to implement it, static version, dynamic version, a mix, use thread pointer register, use a function for retrieval etc.





October 13
On Tuesday, 13 October 2020 at 10:25:35 UTC, IGotD- wrote:
> On Tuesday, 13 October 2020 at 09:32:07 UTC, Denis Feklushkin wrote:
>> Hi!
>>
>> Can anyone explain what "--emulated-tls" actually do?
>>
>> It solves my problem with correct static variables placement on ARM Cortex M3, but I don't know why.
>
> I think it is a compatibility layer that GCC provides. Instead of implementing everything yourself from scratch, GCC provide a framework and a set of hooks you should implement.
>
> http://www.chiark.greenend.org.uk/doc/gcc-4.9-doc/gccint.html#Emulated-TLS
>
> It seems like GCC provides default hooks, so for example if threading is not enabled this TLS emulation layer is probably pretty stupid and do not know what a thread is.

So, compiler knows what this platform is not supports multithreading and does some things wrong with thread static variables if "--emulated-tls" is ommited?

> The variables are dynamically allocated using the C library memory allocation functions.

As I understand, variables allocated by compiler, but it uses internal implict call to __tls_get_addr to provide access to them.

October 13
On Tuesday, 13 October 2020 at 10:35:57 UTC, Denis Feklushkin wrote:
>
> So, compiler knows what this platform is not supports multithreading and does some things wrong with thread static variables if "--emulated-tls" is ommited?
>

You can see the implementation yourself.

https://github.com/gcc-mirror/gcc/blob/master/libgcc/emutls.c

I have used TLS emulation myself and it just works despite the library has no definition of threads or mutexes so I guess these are just stubs or use stubs in the C library in that case. Basically single threaded TLS.

>
> As I understand, variables allocated by compiler, but it uses internal implict call to __tls_get_addr to provide access to them.

If SW call is chosen then __tls_get_addr is the function that is used in order to obtain the address of a TLS variable. If emulation is used this function is just forwarded to the emulation function. It is almost easier to implement __tls_get_addr yourself and skip the emulation. If you look at the emulation layer it is filled with mutexes and mallocs and on simple systems this can be totally avoided if you use your own solution. Especially in real-time systems, the emulation layer should not be used for obvious reasons.

October 13
On Tuesday, 13 October 2020 at 11:02:56 UTC, IGotD- wrote:
> On Tuesday, 13 October 2020 at 10:35:57 UTC, Denis Feklushkin wrote:
>>
>> So, compiler knows what this platform is not supports multithreading and does some things wrong with thread static variables if "--emulated-tls" is ommited?
>>
>
> You can see the implementation yourself.
>
> https://github.com/gcc-mirror/gcc/blob/master/libgcc/emutls.c
>
> I have used TLS emulation myself and it just works despite the library has no definition of threads or mutexes so I guess these are just stubs or use stubs in the C library in that case. Basically single threaded TLS.
>
>>
>> As I understand, variables allocated by compiler, but it uses internal implict call to __tls_get_addr to provide access to them.
>
> If SW call is chosen then __tls_get_addr is the function that is used in order to obtain the address of a TLS variable. If emulation is used this function is just forwarded to the emulation function. It is almost easier to implement __tls_get_addr yourself and skip the emulation.

Ok, I see in my binary what if I use "--emulated-tls" 3-rd party function __tls_get_address (provided by picolibc) replaced by __emutls_get_address.

But it is still not clear why static variables are now not "superimposed" on one another at the same addresses.

> If you look at the emulation layer it is filled with mutexes and mallocs and on simple systems this can be totally avoided if you use your own solution. Especially in real-time systems, the emulation layer should not be used for obvious reasons.

Yes, we already have fibers for this. However, at least one TLS must be created that belongs to the main thread.

October 13
On Tuesday, 13 October 2020 at 11:13:16 UTC, Denis Feklushkin wrote:
>
> But it is still not clear why static variables are now not "superimposed" on one another at the same addresses.
>

If you don't have emulated TLS, your build shouldn't even succeed if you haven't implemented __tls_get_address. So if you have a build that you can test, where does this __tls_get_address come from? Another possibility is that you can use the thread pointer register directly and not use __aeabi_read_tp.__aeabi_read_tp is basically the function that is used for obtaining the thread pointer by SW instead for initial exec model.
October 13
On Tuesday, 13 October 2020 at 11:13:16 UTC, Denis Feklushkin wrote:

>> If SW call is chosen then __tls_get_addr is the function that is used in order to obtain the address of a TLS variable. If emulation is used this function is just forwarded to the emulation function. It is almost easier to implement __tls_get_addr yourself and skip the emulation.
>
> Ok, I see in my binary what if I use "--emulated-tls" 3-rd party function __tls_get_address (provided by picolibc) replaced by __emutls_get_address.
>
> But it is still not clear why static variables are now not "superimposed" on one another at the same addresses.

(I don't spawn threads)


October 13
On Tuesday, 13 October 2020 at 11:23:23 UTC, IGotD- wrote:
> On Tuesday, 13 October 2020 at 11:13:16 UTC, Denis Feklushkin wrote:
>>
>> But it is still not clear why static variables are now not "superimposed" on one another at the same addresses.
>>
>
> If you don't have emulated TLS, your build shouldn't even succeed if you haven't implemented __tls_get_address. So if you have a build that you can test, where does this __tls_get_address come from?

It is provided by "picolibc" library.

Actually it provides __aeabi_read_tp but I wrap it:
https://github.com/denizzzka/d_c_arm_test/blob/master/d/freertos_druntime_backend/external/rt/sections.d#L45
« First   ‹ Prev
1 2