Реализация локального хранилища потоков Linux

__thread Foo foo;

Как "foo" фактически разрешен? Разве компилятор молча заменяет каждый экземпляр "foo" вызовом функции? "Foo" хранится где-то по отношению к нижней части стека, а компилятор сохраняет это как "эй для каждого потока", это пространство у основания стека, а foo хранится как "смещение x из нижней части стека", "?

Ответ 1

Немного сложный (этот документ объясняет это очень подробно), но в принципе это не так. Вместо этого компилятор помещает в исполняемый файл специальный раздел .tdata, содержащий все локальные переменные потока. Во время выполнения создается новая секция данных для каждого потока с копией данных в разделе (только для чтения).tdata, а при переключении потоков во время выполнения раздел также автоматически переключается.

Конечным результатом является то, что переменные __thread так же быстро, как и обычные переменные, и они также не занимают дополнительное пространство стека.