ИМЯ

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 <[email protected]>, Azamat Hackimov <[email protected]>, Hotellook, Nikita <[email protected]>, Spiros Georgaras <[email protected]>, Vladislav <[email protected]>, Yuri Kozlov <[email protected]> и Иван Павлов <[email protected]>
Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.
Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на [email protected]

Recommended readings

Pages related to set_thread_area you should read also:

Questions & Answers

Helpful answers and articles about set_thread_area you may found on these sites:
Stack Overflow Server Fault Super User Unix & Linux Ask Ubuntu Network Engineering DevOps Raspberry Pi Webmasters Google Search