Разработка ядра Linux | страница 32



.

Обычно в ядре на задачи ссылаются непосредственно с помощью указателя на их структуры >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:

>current_thread_info()->task;

Для контраста можно сравнить такой подход с используемым на платформе PowerPC (современный процессор на основе RISC-архитектуры фирмы IBM), для которого значение переменной >current хранится в регистре процессора >r2. На платформе PPC такой подход можно использовать, так как, в отличие от платформы x86, здесь регистры процессора доступны в изобилии. Так как доступ к дескриптору процесса — это очень частая и важная операция, разработчики ядра для платформы PPC сочли правильным пожертвовать одним регистром для этой цели.

Состояние процесса

Поле >state дескриптора процесса описывает текущее состояние процесса (рис. 3.3). Каждый процесс в системе гарантированно находится в одном из пяти различных состояний.

Рис. 3.3. Диаграмма состояний процесса

Эти состояния представляются значением одного из пяти возможных флагов, описанных ниже.

• >TASK_RUNNING — процесс готов к выполнению (runnable). Иными словами, либо процесс выполняется в данный момент, либо находится в одной из очередей процессов, ожидающих на выполнение (эти очереди, >runqueue