MetallicPriest
MetallicPriest

Reputation: 30765

Thread local variables and fs segment

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

Answers (2)

Alan Carre
Alan Carre

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)

  • Alan

Upvotes: 1

NPE
NPE

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

Related Questions