LINUX.ORG.RU

task_struct linux kernel

 , ,


0

1

Как при обработке системного вызова появляется указатель на task_struct. То есть в какой момент она инициализируется?

Вот что то нашел https://www.humblec.com/retrieving-current-processtask_struct-in-linux-kernel/ но как то не особо понятно до конца

★★

Последнее исправление: tyamur (всего исправлений: 1)

Примерно понял. Видимо в момент после вызова сискола из юзерспейса и до самой обработки сискола в ядре. Происходит еще что то типа сохранения адреса возврата и тому подобное. Там видимо и хранится указатель на текущий task_struct. Потом уже соответственно в сисколе достается указатель из стека.

tyamur ★★
() автор топика

http://books.gigatux.nl/mirror/kerneldevelopment/0672327201/ch03lev1sec1.html

On x86, current is calculated by masking out the 13 least significant bits of the stack pointer to obtain the thread_info structure. This is done by the current_thread_info() function. The assembly is shown here:

movl $-8192, %eax
andl %esp, %eax


This assumes that the stack size is 8KB. When 4KB stacks are enabled, 4096 is used in lieu of 8192.

Finally, current dereferences the task member of thread_info to return the task_struct:

current_thread_info()->task;
X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)

У каждого процесса есть не только его код в юзер-спейс, но и связанные с этим процессом структуры в ядре (которые описывают процесс с точки зрения самого ядра). Планировщик заполняет структуру current, когда ставит процесс на исполнение.

Старт нового процесса происходит так – вызывается системный вызов clone(). В ответ он выдает новый pid (идентификатор процесса). Затем, вызывается системный вызов execve(), он загружает новый бинарь в созданный на предыдущем шаге процесс.

Все системные вызовы дергаются не просто так, а от имени какого-либо процесса. Ядро знает какого именно, описатель содержится в структуре current.

Завершение процесса может идти разными путями, но все они сводятся к функции do_exit() в ядре. Эта функция помечена как noreturn, т.е. она исполняется последней в контексте процесса. Выхода из нее не будет. Процесс будет уничтожен и контекст тоже.

Функция do_exit() вызывает exit_notify() для уведомления родительского процесса о завершении дочернего. И далее помечает процесс как не участвующий в дальнейшем распределении времени на исполнение. Планировщик больше не будет его учитывать. Ну а потом все структуры процесса будут уничтожены.

hibou ★★★★★
()
Ответ на: комментарий от hibou

не знаю, понятно ли описал этот момент…

т.е. старт процесса: родитель дергает системный вызов clone()

clone() создает новый процесс, планировщик ставит его на исполнение (когда-нибудь).

и… когда до нового процесса доходит время (очередь на исполнение), он сам загружает в свое тело бинарь через системный вызов execve().

Новый бинарь можно и не грузить, тогда просто останешься копией родителя.

hibou ★★★★★
()
Ответ на: комментарий от tyamur

А это стек чего?

Это ядерный стек. Каждый пользовательский поток имеет два стека: ядерный и пользовательский. При системном вызове происходит прерывание и переключение в режим ядра с ядерным стеком. Код переключения в режим ядра и вызова обработчика прерываний сильно платформо-специфичен.

И в какой момент там оказывается указатель на thread_info?

Когда создаётся поток и его ядерный стек.

X512 ★★★★★
()
Последнее исправление: X512 (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.