O Torvalds Linus

Сайт о *nix системах и всем что с ними связано

Функция do_group_exit()

Mar-24-2012 By root

Функция do group exit о уничтожает все процессы, принадлежащие к группе потоков процесса current. Она принимает в качестве параметра код завершения процесса, который представляет собой либо значение, указанное в системном вызове exit group () (нормальное завершение), либо код ошибки, переданный ядром (аварийное завершение). Функция выполняет следующие действия:

Read the rest of this entry »

Linux использует много других потоков ядра. Другие создаются “по требованию”, когда ядро должно выполнить задачу, для которой оптимальным является собственный контекст ядра.

Примерами потоков ядра (помимо процесса 0 и процесса 1) являются:

keventd (также называемый events) —выполняет функции из рабочей очереди keventd_wq (см. главу 4)\

kapmd —обрабатывает события, имеющие отношение к усовершенствованному управлению питанием (АРМ, Advanced Power Management);

pdflush —сбрасывает грязные”буферы на диск, чтобы утилизировать память;

kblockd —выполняет функции из рабочей очереди kblockd_workqueue. На практике этот поток ядра периодически активизирует драйверы блочных устройств, как описано в разд. ksoftirqd —выполняет тасклеты. У каждого процессора в системе есть один такой поток ядра.

Read the rest of this entry »

Потоки ядра

Mar-22-2012 By root

В традиционных Unix – системах некоторые критические задачи делегируются перемежающимся процессам. Сюда входят сброс дисковых кэшей, выгрузка неиспользуемых страниц, обслуживание сетевых соединений и другие задачи. В самом деле, выполнять эти задачи в строго линейной последовательности неэффективно; их функции и процессы конечного пользователя будут иметь лучшее время отклика, если такие действия выполняются в фоновом режиме. Поскольку некоторые системные процессы работают только в режиме ядра, современные операционные системы делегируют их функции потокам ядра, не обремененным ненужным контекстом пользовательского режима. В Linux потоки ядра отличаются от обычных процессов по следующим пунктам:

? потоки ядра работают только в режиме ядра, а обычные процессы выполняются попеременно то в режиме ядра, то в пользовательском режиме;

? поскольку потоки ядра работают только в режиме ядра, они обращаются только к линейным адресам, большим чем page offset; обычные же процессы пользуются всеми четырьмя гигабайтами линейных адресов, будь то в режиме пользователя или в режиме ядра.

Read the rest of this entry »

Облегченные процессы создаются в Linux с помощью функции clone (), которая принимает следующие параметры:

fn —задает функцию, которую должен выполнить новый процесс; когда эта функция возвратит управление, потомок завершит свою работу. Функция возвращает целое число, представляющее собой код возврата процес – са – потомка;

arg —указывает на данные, необходимые для функции fn ();

flags —разнообразная информация. Младший байт задает номер сигнала, посылаемого родителю, когда потомок завершит работу (как правило, выбирается сигнал sigchld). Остальные три байта задают группу флагов клона, перечисленных в табл. 3.8;

chiid stack —задает указатель стека в режиме пользователя, который должен быть записан в регистр esp процесса – потомка. Вызывающий процесс (родитель) должен всегда выделять стек для нового потомка;

tis —задает адрес структуры, определяющей сегмент локальной памяти потока для нового облегченного процесса (см. главу 2). Имеет смысл только при установленном флаге clone settls;

ptid —задает адрес переменной процесса – родителя в режиме пользователя, где будет храниться идентификатор нового облегченного процесса. Имеет смысл только при установленном флаге clone parent settid;

ctid —задает адрес переменной нового облегченного процесса в режиме пользователя, где будет храниться идентификатор этого процесса. Имеет смысл только при установленном флаге clone child settid.

Read the rest of this entry »

При удовлетворении запросов пользователей Unix – подобные операционные системы активно создают новые процессы. Например, всякий раз, когда пользователь вводит команду, оболочка создает новый процесс, который выполняет еще одну копию оболочки.

Традиционные Unix – системы обращаются со всеми процессами одинаково: ресурсы, которыми обладает процесс – родитель, дублируются в процессах – потомках. Такой подход делает процедуру создания процессов очень медленной и неэффективной, потому что включает в себя копирование всего адресного пространства процесса – родителя. Процессу – потомку редко нужно читать или модифицировать все ресурсы, унаследованные от родителя; в большинстве случаев он тут же делает системный вызов execve () и очищает столь заботливо скопированное адресное пространство.

Когда один из этих процессов попытается сделать запись в физическую страницу, ядро копирует ее содержимое в новую физическую страницу, которая присваивается пишущему процессу;
облегченные процессы позволяют как родителю, так и потомку совместно использовать многие структуры данных ядра, назначаемые процессам. Сюда входят таблицы страниц (и, следовательно, все адресное пространство режима пользователя, таблицы открытых файлов и диспозиций сигналов);
системный вызов vforko создает процесс, который использует адресное пространство своего родителя. Чтобы не позволить родителю переписать данные, необходимые потомку, выполнение родителя задерживается до тех пор, пока потомок не закончит свою работу или не запустит новую программу.

Содержимое регистров с плавающей точкой не восстанавливается сразу после того, как возобновляется выполнение процесса next. Однако флаг ts в

регистре его был установлен макросом uniazy_fpu (), поэтому, как только процесс next попытается выполнить инструкцию ESCAPE, MMX или SSE/SSE2, управляющий блок возбудит исключение “Устройство недоступно”, а ядро (точнее, обработчик этого исключения) вызовет функцию math state restore (). В этом обработчике процесс next идентифицируется как current.

Read the rest of this entry »

Начиная с Intel 80486DX, блок операций с плавающей точкой (Floating Point Unit, FPU) интегрирован в процессор. Тем не менее название математический сопроцессор используется по-прежнему и напоминает о тех днях, когда вычисления с плавающей точкой выполнялись дорогим специализированным чипом. Для поддержки совместимости со старыми моделями арифметические функции выполняются при помощи ESCAPE – инструкций, т. е. инструкций с префиксным байтом, имеющим значение от 0xd8 до Oxdf. Эти инструкции работают с набором процессорных регистров для операций с плавающей точкой. Очевидно, что если процесс использует ESCAPE – инструкции, то содержимое регистров с плавающей точкой является частью его аппаратного контекста и должно быть сохранено. Впоследствии компания Intel встроила в свои микропроцессоры Pentium новый набор ассемблерных инструкций. Они получили название MMX – инструкций и были задуманы для ускорения работы мультимедийных приложений. MMX – инструкции используют регистры блока операций с плавающей точкой (блока FPU).

Read the rest of this entry »

Макрос switch__to

Mar-17-2012 By root

Второй шаг переключения процессов выполняется макросом switch to. Это одна из наиболее аппаратно – зависимых процедур ядра, и для понимания ее действий требуются некоторые усилия.

Во-первых, макрос принимает три параметра, prev, next и last. Нетрудно догадаться о назначении параметров prev и next: они играют ту же роль, что и локальные переменные prev и next, т. е. являются входными параметрами, задающими ячейки памяти, хранящие адреса дескрипторов замещаемого процесса и замещающего процесса соответственно.

Read the rest of this entry »

Поле thread

Mar-16-2012 By root

При каждом переключении процессов аппаратный контекст замещаемого процесса должен быть где-то сохранен. Он не может быть сохранен в сегменте состояния задачи, что соответствовало бы подходу Intel, т. к. в Linux используется один сегмент состояния задачи для всех процессов, а не отдельный сегмент для каждого процесса.

Поэтому дескриптор процесса включает в себя поле thread типа thread_ struct, в котором ядро сохраняет аппаратный контекст, когда происходит переключение с этого процесса на другой. Как мы увидим далее, эта структура имеет поля почти для всех регистров процессора, кроме регистров общего назначения еах, еЬх и др., которые сохраняются в стеке режима ядра.

Выполнение переключения процессов

Мы по-прежнему будем предполагать, что prev указывает на дескриптор замещаемого процесса, a next -на дескриптор активизируемого процесса. Как мы увидим, prev и next являются локальными переменными функции schedule().

В архитектуре 80×86 имеется специальный тип сегмента для хранения аппаратных контекстов —сегмент состояния задачи, или сегмент TSS (Task State Segment). Хотя операционная система Linux не применяет аппаратное переключение контекста, она все же вынуждена устанавливать сегмент состояния задачи для каждого процессора в системе. Это делается, в основном, по двум причинам:

когда процессор 80×86 переключается из пользовательского режима в режим ядра, он извлекает адрес стека режима ядра из сегмента TSS;

Read the rest of this entry »