O Torvalds Linus

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

Archive for the ‘Linux’ Category

В то время как адресное пространство у каждого процесса свое, всем процессам приходится делить между собой регистры процессора. Аппаратный контекст является подмножеством контекста выполнения процесса, включающего в себя всю информацию, необходимую для выполнения процесса. В 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 »

Очереди ожидания

Mar-11-2012 By root

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

Поскольку очереди ожидания модифицируются обработчиками прерываний и основными функциями ядра, двунаправленные списки должны быть защищены от попыток одновременного обращения, которые могут привести к непредсказуемым результатам. Синхронизация достигается с помощью спин – блокировки lock, хранящейся в голове очереди. Поле task list является головой списка ожидающих процессов.

Read the rest of this entry »

В списках очереди на выполнение собраны все процессы, имеющие состояние task running. Linux стоит перед следующим выбором:

Процессы в состояниях task_stopped, exit_zombie и exit_dead не объединяются в специальные списки. Нет никакой необходимости группировать эти процессы, поскольку остановленные, зомбированные”и мертвые”процессы доступны только через их идентификаторы или связные списки потомков конкретного родителя.

Процессы в состояниях task_interruptible или task_uninterruptible подразделяются на много классов, каждый из которых соответствует определенному событию.

Возможно, вы желаете знать, откуда взялась константа 0х9еЗ 70001 (= 2 654 404 609). Данная хеш – функция основана на умножении индекса на подходящее большое число с такой целью, чтобы результат вызвал переполнение, и значение 32 – битовой переменной можно было считать результатом операции деления с остатком. Кнут предположил, что хорошие результаты можно получить, когда большой сомножитель является простым числом, примерно равным золотому сечению от 232 (32 бита —это размер регистров в архитектуре 80×86). Число 2 654 404 609 является простым, близким к 232х(л/5 —1)/2. Кроме того, на него легко умножать, выполняя сложение и сдвиг битов, потому что оно равно 231 + 229-225 + 222-219-216 + 1.

Read the rest of this entry »

Процессы, создаваемые программой, находятся в отношениях ”родитель – потомок”. Когда процесс создает несколько потомков, между ними возникают отношения “братства”. Несколько полей в дескрипторе процесса отражают эти взаимоотношения. Они перечислены для некоторого процесса Р. Процессы 0 и 1 создаются ядром. Как мы увидим далее в этой главе, процесс 1 (называемый init) является предком всех остальных процессов.

Процесс РО последовательно создал процессы PI, Р2 и РЗ. Процесс может быть лидером в группе или в сеансе, он может быть лидером в группе потоков, а также он может отслеживать выполнение других процессов. Поля дескриптора процесса, которые определяют отношения между процессом Р и остальными процессами.

Read the rest of this entry »

Список процессов

Mar-7-2012 By root

Первым примером двунаправленного списка, который мы рассмотрим, является список процессов, в котором собраны вместе все дескрипторы процессов. Каждая структура task struct включает в себя поле tasks типа list head, чьи поля prev и next указывают, соответственно, на предыдущий и следующий элемент task struct.

Голова списка процессов представляет собой дескриптор init task типа task struct. Это дескриптор так называемого процесса 0, или процесса swapper. Поле tasks ->prev дескриптора init task указывает на поле tasks процесса, занесенного в список последним.

Read the rest of this entry »

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

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

Read the rest of this entry »

Тесная связь между структурой thread info и стеком режима ядра, описанная в предыдущем разделе, предлагает эффективное решение: ядро может легко вычислить адрес структуры thread info текущего процесса по значению регистра esp. В самом деле, если структура thread union имеет длину 8 Кбайт (213 байт), то ядро маскирует 13 младших битов регистра esp, чтобы получить базовый адрес структуры thread info. С другой стороны, если структура thread union имеет длину 4 Кбайт, ядро маскирует 12 младших битов регистра esp. Это делается с помощью функции current thread info (), которая выполняет примерно следующие ассемблерные инструкции:

Read the rest of this entry »