Вход/Регистрация
Разработка ядра Linux
вернуться

Лав Роберт

Шрифт:

Ядро хранит информацию о всех процессах в двухсвязном списке, который называется task list [10] (список задач). Каждый элемент этого списка является дескриптором процесса и имеет тип структуры

struct task_struct
, которая описана в файле
include/linux/sched.h
. Дескриптор процесса содержит всю информацию об определенном процессе.

Структура

task_struct
— достаточно большая структура данных размером порядка 1,7 Кбайт на 32-разрядной машине. Однако этот размер не такой уж большой, учитывая, что в данной структуре содержится вся информация о процессе, которая необходима ядру. Дескриптор процесса содержит данные, которые описывают выполняющуюся программу, — открытые файлы, адресное пространство процесса, ожидающие на обработку сигналы, состояние процесса и многое другое (рис. 3.1).

10

Иногда в литературе по построению операционных систем этот список называется task array (массив задач). Поскольку в ядре Linux используется связанный список, а не статический массив, его называют task list.

Рис. 3.1. Дескриптор процесса и список задач

Выделение дескриптора процесса

Память для структуры

task_struct
выделяется с помощью подсистемы выделения памяти, которая называется слябовый распределитель (slab allocator), для возможности повторного использования объектов и раскрашивания кэша (cache coloring) (см. главу 11, "Управление памятью"). В ядрах до серии 2.6 структура
task_struct
хранилась в конце стека ядра каждого процесса. Это позволяет для аппаратных платформ, у которых достаточно мало регистров процессора (как, например, платформа x86), вычислять местоположение дескриптора процесса, только зная значение регистра указателя стека (stack pointer), без использования дополнительных регистров для хранения самого адреса этого местоположения. Так как теперь дескриптор процесса создается с помощью слябового распределителя, была введена новая структура
thread_info
, которая хранится в области дна стека (для платформ, у которых стек растет в сторону уменьшения значения адреса памяти) или в области вершины стека (для платформ, у которых стек растет в сторону увеличения значения адреса памяти) [11] (рис. 3.2.).

11

Причиной создания структуры

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

Рис 3.2. Дескриптор процесса и стек ядра

Структура

struct thread_info
для платформы x86 определена в файле
<asm/thread_info.h>
в следующем виде.

struct thread_info {

 struct task_struct *task;

 struct exec_domain *exec_domain;

 unsigned long flags;

 unsigned long status;

 __u32 cpu;

 __s32 preempt_count;

 mm_segment_t addr_limit;

 struct restart_block restart_block;

 unsigned long previous_esp;

 __u8 supervisor_stack[0];

};

Для каждой задачи ее структура

thread_info
хранится в конце стека ядра этой задачи. Элемент структуры
thread_info
с именем
task
является указателем на структуру
task_struct
этой задачи.

Хранение дескриптора процесса

Система идентифицирует процессы с помощью уникального значения, которое называется идентификатором процесса (process identification, PID). Идентификатор

PID
 — это целое число, представленное с помощью скрытого типа
pid_t
[12] , который обычно соответствует знаковому целому—
int
.

Однако, для обратной совместимости со старыми версиями ОС Unix и Linux максимальное значение этого параметра по умолчанию составляет всего лишь 32768 (что соответствует типу данных

short int
). Ядро хранит значение данного параметра в поле
pid
дескриптора процесса.

12

Скрытый тип (opaque type) — это тип данных, физическое представление которого неизвестно или не существенно.

Это максимальное значение является важным, потому что оно определяет максимальное количество процессов, которые одновременно могут существовать в системе. Хотя значения 32768 и достаточно для офисного компьютера, для больших серверов может потребоваться значительно больше процессов. Чем меньше это значение, тем скорее нумерация процессов будет начинаться сначала, что приводит к нарушению полезного свойства: больший номер процесса соответствует процессу, который запустился позже. Если есть желание нарушить в системе обратную совместимость со старыми приложениями, то администратор может увеличить это максимальное значение во время работы системы с помощью записи его в файл

/proc/sys/kernel/pid_max
.

Обычно в ядре на задачи ссылаются непосредственно с помощью указателя на их структуры

task_struct
. И действительно, большая часть кода ядра, работающего с процессами, работает прямо со структурами
task_struct
. Следовательно, очень полезной возможностью было бы быстро находить дескриптор процесса, который выполняется в данный момент, что и делается с помощью макроса current. Этот макрос должен быть отдельно реализован для всех поддерживаемых аппаратных платформ. Для одних платформ указатель на структуру
task_struct
процесса, выполняющегося в данный момент, хранится в регистре процессора, что обеспечивает более эффективный доступ. Для других платформ, у которых доступно меньше регистров процессора, чтобы зря не тратить регистры, используется тот факт, что структура
thread_info
хранится в стеке ядра. При этом вычисляется положение структуры
thread_info
, а вслед за этим и адрес структуры
task_struct
процесса.

Для платформы x86 значение параметра

current
вычисляется путем маскирования 13 младших бит указателя стека для получения адреса структуры
thread_info
. Это может быть сделано с помощью функции
current_thread_info
. Соответствующий код на языке ассемблера показан ниже.

movl $-8192, %eax

andl %esp, %eax

Окончательно значение параметра

current
получается путем разыменования значения поля
task
полученной структуры
thread_info
:

  • Читать дальше
  • 1
  • ...
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: