Provided by: manpages-ru-dev_4.27.0-1_all bug

НАИМЕНОВАНИЕ

       get_thread_area, set_thread_area - управляют информацией области локального хранилища нити

БИБЛИОТЕКА

       Стандартная библиотека языка C (libc, -lc)

ОБЗОР

       #include <sys/syscall.h>     /* определения констант SYS_* */
       #include <unistd.h>

       #if defined __i386__ || defined __x86_64__
       # include <asm/ldt.h>        /* определения struct user_desc */

       int syscall(SYS_get_thread_area, struct user_desc *u_info);
       int syscall(SYS_set_thread_area, struct user_desc *u_info);

       #elif defined __m68k__

       int syscall(SYS_get_thread_area);
       int syscall(SYS_set_thread_area, unsigned long tp);

       #elif defined __mips__ || defined __csky__

       int syscall(SYS_set_thread_area, unsigned long addr);

       #endif

       Примечание:  glibc не предоставляет обёрточных функций для этих системных вызовов, что делает необходимым
       использование syscall(2).

ОПИСАНИЕ

       These calls provide architecture-specific support for a  thread-local  storage  implementation.   At  the
       moment,  set_thread_area()  is available on m68k, MIPS, C-SKY, and x86 (both 32-bit and 64-bit variants);
       get_thread_area() is available on m68k and x86.

       On m68k, MIPS and C-SKY, set_thread_area()  allows storing an  arbitrary  pointer  (provided  in  the  tp
       argument  on  m68k  and  in the addr argument on MIPS and C-SKY)  in the kernel data structure associated
       with the calling thread; this pointer can later be retrieved using get_thread_area()  (see also NOTES for
       information regarding obtaining the thread pointer on MIPS).

       На x86 в Linux под локальное хранилище нити отдано три элемента глобальной  таблицы  дескрипторов  (GDT).
       Подробней о GDT читайте в Intel Software Developer's Manual или AMD Architecture Programming Manual.

       Этим системным вызовам передаётся указатель на структуру вида:

           struct user_desc {
               unsigned int  entry_number;
               unsigned int  base_addr;
               unsigned int  limit;
               unsigned int  seg_32bit:1;
               unsigned int  contents:2;
               unsigned int  read_exec_only:1;
               unsigned int  limit_in_pages:1;
               unsigned int  seg_not_present:1;
               unsigned int  useable:1;
           #ifdef __x86_64__
               unsigned int  lm:1;
           #endif
           };

       Вызов  get_thread_area() читает элемент GDT, указанный в u_info->entry_number и заполняет оставшиеся поля
       в u_info.

       Вызов set_thread_area() изменяет элемент TLS в GDT.

       Элемент массива TLS, устанавливаемый  set_thread_area(),  соответствует  значению   u_info->entry_number,
       которое  передал  пользователь.  Если  это значение находится в допустимых пределах, то set_thread_area()
       записывает дескриптор TLS, на который указывает u_info, в массив TLS нити.

       Когда set_thread_area() передаётся entry_number со значением -1, то ищется свободный  элемент  TLS.  Если
       set_thread_area()  находит  свободный элемент TLS, то значение u_info->entry_number устанавливается после
       возврата для показа того, какой же элемент был изменён.

       Структура user_desc считается «пустой», если read_exec_only и seg_not_present равны 1,  а  все  остальные
       поля  равны  0.  Если  «пустой» дескриптор передаётся в set_thread_area(), то соответствующий элемент TLS
       будет очищен. Дополнительную информацию смотрите в разделе ДЕФЕКТЫ.

       Начиная с Linux 3.19, set_thread_area() нельзя использовать для записи отсутствующих сегментов, 16-битных
       сегментов или сегментов кода, но допускается очистка таких сегментов.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

       On x86, these system calls return 0 on success, and -1 on failure, with errno set to indicate the error.

       On C-SKY, MIPS and m68k, set_thread_area()  always returns 0.  On m68k,  get_thread_area()   returns  the
       thread area pointer value (previously set via set_thread_area()).

ОШИБКИ

       EFAULT u_info является некорректным указателем.

       EINVAL u_info->entry_number вне допустимых границ.

       ENOSYS Вызов get_thread_area() или set_thread_area() был вызван как 64-битный системный вызов.

       ESRCH  (set_thread_area()) Невозможно найти свободный элемент TLS.

СТАНДАРТЫ

       Linux.

ИСТОРИЯ

       set_thread_area()
              Linux 2.5.29.

       get_thread_area()
              Linux 2.5.32.

ПРИМЕЧАНИЯ

       These system calls are generally intended for use only by threading libraries.

       На  x86 вызов arch_prctl(2) может влиять на set_thread_area(). Подробней смотрите в arch_prctl(2). Обычно
       это не вызывает проблем, так как arch_prctl(2) обычно используется только в 64-битных программах.

       На MIPS текущее значение указателя области нити можно получить с помощью инструкции:

           rdhwr dest, $29

       Эта инструкция ловится и обрабатывается ядром.

ОШИБКИ

       В 64-битных ядрах до Linux 3.19, если был установлен  один  из  битов  заполнения  в  user_desc,  то  это
       приводило  к тому, что дескриптор не считался пустым (смотрите modify_ldt(2)). В результате, единственным
       надёжным способом очистить элемент  TLS  было  задействование  memset(3)  для  обнуления  всей  структуры
       user_desc,  включая  биты  заполнения,  и затем установка битов read_exec_only и seg_not_present. В Linux
       3.19, структура user_desc, полностью  состоящая  из  нулей  кроме  entry_number,  также  будет  считаться
       запросом на очистку элемента TLS, что отличается от работы старых ядер.

       До Linux 3.19, сегментные регистры DS и ES не должны ссылаться на элементы TLS.

СМОТРИТЕ ТАКЖЕ

       arch_prctl(2), modify_ldt(2), ptrace(2)  (PTRACE_GET_THREAD_AREA and PTRACE_SET_THREAD_AREA)

ПЕРЕВОД

       Русский  перевод  этой  страницы  руководства разработал(и) Alexander Golubev <fatzer2@gmail.com>, Azamat
       Hackimov  <azamat.hackimov@gmail.com>,  Hotellook,   Nikita   <zxcvbnm3230@mail.ru>,   Spiros   Georgaras
       <sng@hellug.gr>,  Vladislav  <ivladislavefimov@gmail.com>,  Yuri Kozlov <yuray@komyakino.ru>, Иван Павлов
       <pavia00@gmail.com> и Kirill Rekhov <krekhov.dev@gmail.com>

       Этот перевод является свободной программной документацией; он распространяется на условиях  общедоступной
       лицензии  GNU  (GNU  General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или
       более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

       Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите  об  этом
       разработчику(ам)   по   его(их)  адресу(ам)  электронной  почты  или  по  адресу  списка рассылки русских
       переводчиков.

Справочные страницы Linux 6.9.1                   2 мая 2024 г.                               set_thread_area(2)