Provided by: manpages-ru-dev_4.19.0-7_all bug

ИМЯ

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

LIBRARY

       Standard C library (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__

       int syscall(SYS_set_thread_area, unsigned long addr);

       #endif

       Note:  glibc  provides  no  wrappers  for  these  system  calls,  necessitating the use of
       syscall(2).

ОПИСАНИЕ

       Эти вызовы предоставляют зависимую от архитектуры реализацию поддержки информации  области
       локального  хранилища  нити.  В настоящее время вызов set_thread_area() доступен для m68k,
       MIPS и x86 (32-битный и 64-битный вариант); get_thread_area() доступен для m68k и x86.

       Для m68k и MIPS, set_thread_area() позволяет сохранить произвольный указатель (указанный в
       аргументе  tp  на  m68k  и  в  аргументе  addr на MIPS) структуре данных ядра, связанной с
       вызывающей нитью; этот указатель позднее может быть получен  с  помощью  get_thread_area()
       (информацию о получении указателя нити на 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.

       На   MIPS   и   m68k   вызов   set_thread_area()   всегда  возвращает  0.  На  m68k  вызов
       get_thread_area() возвращает значение указателя области нити (установленный ране с помощью
       set_thread_area()).

ОШИБКИ

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

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

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

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

ВЕРСИИ

       Вызов set_thread_area() появился в версии 2.5.29. Вызов get_thread_area() появился в Linux
       2.5.32.

СТАНДАРТЫ

       Вызовы  set_thread_area()  и  get_thread_area()  есть  только  в  Linux,  и  они не должны
       использоваться в переносимых программах.

ЗАМЕЧАНИЯ

       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>

       Этот  перевод  является  бесплатной  документацией;  прочитайте  Стандартную  общественную
       лицензию GNU версии 3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если  вы  обнаружите  ошибки  в  переводе этой страницы руководства, пожалуйста, отправьте
       электронное письмо на ⟨man-pages-ru-talks@lists.sourceforge.net⟩.