Локальные переменные потока и сегмент fs

Я читаю из локальной переменной потока в своем коде следующим образом:

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

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

movslq %fs:0xfffffffffffffffc,%rbx

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


person MetallicPriest    schedule 05.01.2012    source источник


Ответы (2)


Да, это вполне могла быть правильная инструкция. Из 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

person NPE    schedule 05.01.2012
comment
Но как это должно работать? Как разные потоки имеют разные сегменты fs? - person MetallicPriest; 05.01.2012
comment
@MetallicPriest: Ну, у каждого потока есть свой собственный набор значений регистров (для всех регистров, а не только fs). - person NPE; 05.01.2012
comment
Насчет регистров, да, я знаю, что у каждого потока свои. Но я немного удивлен по поводу fs. Я предполагаю, что сегмент fs не должен быть очень большим, иначе его пришлось бы сохранять каждый раз, когда происходит переключение контекста. - person MetallicPriest; 05.01.2012
comment
@MetallicPriest: сегмент не сохраняется, сохраняется значение регистра, указывающее на сегмент. Каждый поток имеет различное значение fs. - person NPE; 05.01.2012
comment
@MetallicPriest: Вы можете прочитать, как TLS работает в Linux, на странице akkadia.org/drepper/tls.pdf < / а> - person janneb; 05.01.2012
comment
@aix, интересно, архитекторы x86 очень умничают, чтобы придумать такую ​​схему :)! - person MetallicPriest; 05.01.2012

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

Бывший. FS = 1B (который является обычным селектором «CS» для Win NT) - это сегмент локального потока.

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

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

0000 0000 0001 1011

or

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

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

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

  • Алан
person Alan Carre    schedule 03.03.2014