views:

62

answers:

1
__thread Foo foo;

How is "foo" actually resolved? Does the compiler silently replace every instance of "foo" with a function call? Is "foo" stored somewhere relative to the bottom of the stack, and the compiler stores this as "hey, for each thread, have this space near the bottom of the stack, and foo is stored as 'offset x from bottom of stack'"?

+2  A: 

It's a little complicated (this document explains it in great detail), but it's basically neither. Instead the compiler puts a special .tdata section in the executable, which contains all the thread-local variables. At runtime, a new data section for each thread is created with a copy of the data in the (read-only) .tdata section, and when threads are switched at runtime, the section is also switched automatically.

The end result is that __thread variables are just as fast as regular variables, and they don't take up extra stack space, either.

Dean Harding
I can see how this work if I have multi threads but only one core. When I have multi threads and multi core, how does this .tdata section work?
anon
@anon: What differences do you see in your second case?
Roger Pate
time 01: core 1 runs thread 1; swaps in thread 1's .tdata;time 02: core 2 runs thread 2; swaps in thread 2's .tdata;Now isn't thread1 suddenly using thread2's .tdata?
anon
@anon: Linux threads are actually separate processes with most of their resources shared (e.g. most of their memory space), but all resources don't have to be shared; `man 2 clone` may be helpful. You can write a test program for the situation you describe.
Roger Pate
How do I print out the address of .tdata that belongs to a particular thread?
anon
I don't believe you can, but the address of individual variables will be different so you can just print out the address of a single __thread variable from different threads and see that they're different.
Dean Harding