Thread variables locales et segment fs

Je lis depuis une variable locale de thread dans mon code comme ceci,

// tid_local is declared as __thread int tid_local; long tid = tid_local 

En parcourant le code dissemblé, j’ai vu quelque chose comme ceci, qui est probablement l’instruction qui assigne tid en lisant tid_local .

 movslq %fs:0xfffffffffffffffc,%rbx 

Maintenant, ma question est de savoir si cela peut vraiment être l’instruction qui fait ceci, c’est-à-dire lire la variable du thread local et si gcc utilise toujours le segment fs pour stocker les variables locales du thread. Comment est-ce censé fonctionner?

Oui, cela pourrait bien être la bonne instruction. A partir du manuel de gcc :

-mtls-direct-seg-refs

-mno-tls-direct-seg-refs

Contrôle si les variables TLS sont accessibles avec des décalages du registre de segment TLS ( % gs pour 32 bits,% fs pour 64 bits ) ou si le pointeur de base de thread doit être ajouté. Le fait que ce soit légal ou non dépend du système d’exploitation et du fait qu’il mappe le segment pour couvrir l’ensemble de la zone TLS.

edit Voici un excellent lien suggéré par @janneb dans les commentaires: http://www.akkadia.org/drepper/tls.pdf

La façon dont les différents threads peuvent avoir différents segments fs est implémentée en configurant des tables de descripteurs locaux (LDT) par thread. Lorsqu’un changement de thread se produit, le processeur charge automatiquement les descripteurs de segment “thread-local” du LDT correspondant. Vous pouvez vérifier si c’est le cas en examinant la valeur de FS. Si le bit 3 est 1, alors il utilise un LDT.

Ex. FS = 1B (qui se trouve être le sélecteur “CS” habituel sous Windows NT) est un segment local de thread.

Vous travaillez comme suit:

Le sélecteur en binary est

0000 0000 0001 1011

ou

Index = 0000 0000 0001 [12 bits] (2ème entrée dans DT)

Table des descripteurs = 1 [1 bits] (1 == local, 0 == global)

RPL = 011 [3 bits] (niveau de privilège demandé = 3)

  • Alan