Reputation: 30765
I am reading from a thread local variable in my code like this,
// tid_local is declared as __thread int tid_local;
long tid = tid_local
Looking around the dissassembled code, I saw something like this, which I suspect is the instruction which assigns tid by reading tid_local.
movslq %fs:0xfffffffffffffffc,%rbx
Now my question is if this can really be the instruction which is doing this, that is, reading from the local thread variable and if gcc always uses the fs segment for storing thread local variables. How is this supposed to work?
Upvotes: 10
Views: 3638
Reputation: 11
The way different threads can have different fs segments is implemented by setting up local descriptor tables (LDTs) on a per-thread basis. When a thread switch occurs the processor automatically loads the any "thread-local" segment descriptors from the corresponding LDT. You can verify if that's the case by looking at the value of FS. If bit 3 is 1 then it is using an LDT.
Ex. FS = 1B (which happens to be the usual "CS" selector for under Win NT) is a thread-local segment.
You work it out as follows:
The selector in binary is
0000 0000 0001 1011
or
Index=0000 0000 0001 [12 bits] (2nd entry in DT)
Descriptor Table=1 [1 bits] (1 == local, 0 == global)
RPL=011 [3 bits] (Requested Privilege level = 3)
Upvotes: 1
Reputation: 500327
Yes, this could well be the right instruction. From the gcc
manual:
-mtls-direct-seg-refs
-mno-tls-direct-seg-refs
Controls whether TLS variables may be accessed with offsets from the TLS segment register (%gs for 32-bit, %fs for 64-bit), or whether the thread base pointer must be added. Whether or not this is legal depends on the operating system, and whether it maps the segment to cover the entire TLS area.
edit Here is an excellent link suggested by @janneb in the comments: http://www.akkadia.org/drepper/tls.pdf
Upvotes: 12