O Torvalds Linus

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

Операционная система Unix позволяет процессу опрашивать ядро на предмет идентификатора процесса родителя или состояния любого своего потомка. Например, процесс может создать процесс – потомок для решения конкретной задачи, а затем вызвать какую-нибудь wait ()подобную библиотечную функцию, чтобы проверить, завершилось ли выполнение потомка. Если завершилось, код завершения позволит родителю судить об успешности решения задачи.

Чтобы не возникло противоречий с такими возможностями, ядрам Unix не разрешается уничтожать данные, содержащиеся в дескрипторе процесса, сразу после завершения процесса. Им можно сделать это только после того, как процесс – родитель сделает wait ()подобный системный вызов в отношении завершившегося процесса. Именно поэтому было введено состояние exit zombie: хотя в техническом смысле процесса больше нет, его дескриптор хранится, пока процесс – родитель не будет уведомлен.

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 »

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

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

Read the rest of this entry »

В то время как адресное пространство у каждого процесса свое, всем процессам приходится делить между собой регистры процессора. Аппаратный контекст является подмножеством контекста выполнения процесса, включающего в себя всю информацию, необходимую для выполнения процесса. В Linux часть аппаратного контекста процесса хранится в дескрипторе процесса, а остальная его часть —в стеке режима ядра.

Далее в тексте мы подразумеваем, что локальная переменная prev ссылается на дескриптор процесса, с которого происходит переключение, а переменная next —на дескриптор замещающего процесса, т. е. процесса, на который происходит переключение. Тогда мы может определить переключение процессов как действия по сохранению аппаратного контекста процесса prev и замене его на аппаратный контекст процесса next.

Read the rest of this entry »

У каждого процесса есть ограничения на ресурсы, которые определяют объем системных ресурсов, предоставляемых ему в пользование. Эти ограничения не позволяют пользователю злоупотреблять системными ресурсами (процессорным временем, дисковым пространством и т. д.). Linux поддерживает ограничения на ресурсы.

Ограничения на ресурсы для текущего процесса хранятся в поле current -> signai ->riim, т. е. в поле дескриптора сигнала этого процесса. Это поле представляет собой массив элементов типа struct riimit, по одному на каждое ограничение ресурса:

struct riimit (

unsigned long rlim_cur; unsigned long rlim_max;

);

Read the rest of this entry »

Новую голову очереди ожидания можно создать с помощью макроса

DECLARE_WAIT_QUEUE_HEAD (паше), КОТОрЫЙ СТаТИЧеСКИ объявляет НОВуЮ Переменную с именем паше в качестве головы очереди ожидания и инициализирует ее ПОЛЯ lock И task list. Функция init waitqueue head () может быть ИСпользована для инициализации головы очереди ожидания, для которой переменная была выделена динамически.

ФуНКЦИЯ init waitqueue entry (q,p) инициализирует Структуру q ТИПа wait queue t Следующим образом:

q ->flags = 0; q ->task = р;

q ->func = default_wake_function;

He эксклюзивный процесс p будет разбужен функцией defauit_wake_ function о, которая является интерфейсной функцией для try_to_wake_up().

Read the rest of this entry »