Потоковые локальные переменные и сегмент fs - PullRequest
10 голосов
/ 05 января 2012

Я читаю из локальной переменной потока в моем коде, как это,

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

Осматривая разобранный код, я увидел нечто подобное, и я подозреваю, что это инструкция, которая присваивает tid , читая tid_local .

movslq %fs:0xfffffffffffffffc,%rbx

Теперь мой вопрос: действительно ли это может быть инструкция, которая делает это, то есть читает из локальной переменной потока, и если gcc всегда использует сегмент fs для хранения локальных переменных потока. Как это должно работать?

Ответы [ 2 ]

12 голосов
/ 05 января 2012

Да, это вполне может быть правильной инструкцией. Из gcc руководства :

-mtls-direct-seg-refs

-mno-tls-direct-seg-refs

Управляет возможностью доступа к переменным TLS с помощью смещений из регистра сегмента TLS (% gs для 32-разрядного,% fs для 64-разрядного ) или необходимости добавления указателя базы потока. Является ли это законным, зависит от операционной системы и от того, соответствует ли сегмент сегменту всей области TLS.

edit Вот отличная ссылка, предложенная @janneb в комментариях: http://www.akkadia.org/drepper/tls.pdf

1 голос
/ 03 марта 2014

Способ, которым разные потоки могут иметь разные сегменты fs, реализуется путем настройки локальных таблиц дескрипторов (LDT) для каждого потока.Когда происходит переключение потока, процессор автоматически загружает любые дескрипторы сегмента «локальный поток» из соответствующего LDT.Вы можете проверить, так ли это, посмотрев на значение FS.Если бит 3 равен 1, то он использует LDT.

Пример.FS = 1B (который является обычным селектором "CS" для Win NT) является локальным потоком сегментом.

Вы работаете следующим образом:

Селектор в двоичном

0000 0000 0001 1011

или

Индекс = 0000 0000 0001 [12 бит] (2-я запись в DT)

Таблица дескрипторов = 1 [1биты] (1 == локальный, 0 == глобальный)

RPL = 011 [3 бита] (запрошенный уровень привилегий = 3)

  • Alan
...