Показанный код уменьшает значение кванта времени процесса и проверяет, не стало ли это значение равным нулю. Если стало, то задание является истекшим и его необходимо поместить в один из массивов. Для этого код вначале проверяет интерактивность задания с помощью макроса TASK_INTERACTIVE()
. Этот макрос на основании значения параметра nice рассчитывает, является ли задание "достаточно интерактивным". Чем меньше значение EXPIRED_STARVING()
, проверяет, нет ли в истекшем массиве процессов, особенно
Переход в приостановленное состояние и возврат к выполнению
Приостановленное состояние задачи (состояние ожидания, заблокированное состояние, read()
для файла, который необходимо считать с диска. Еще один пример— задача может ожидать на ввод данных с клавиатуры. В любом случае ядро ведет себя одинаково: задача помечает себя как находящуюся в приостановленном состоянии, помещает себя в очередь ожидания (wail queue), удаляет себя из очереди выполнения и вызывает функцию schedule()
для выбора нового процесса на выполнение. Возврат к выполнению (wake up) происходит в обратном порядке: задача помечает себя как готовую к выполнению, удаляет себя из очереди ожидания и помещает себя в очередь выполнения.
Как указывалось в предыдущей главе, с приостановленным состоянием связаны два значения поля состояния процесса: TASK_INTERRUPTIBLE
и TASK_UNINTERRUPTIBLE
. Они отличаются только тем, что в состоянии TASK_UNINTERRUPTIBLE
задача игнорирует сигналы, в то время как задачи в состоянии TASK_INTERRUPTIBLE
возвращаются к выполнению преждевременно и обрабатывают пришедший сигнал. Оба типа задач, находящихся в приостановленном состоянии, помещаются в очередь ожидания, ожидают наступления некоторого события и не готовы к выполнению.
Приостановленное состояние обрабатывается с помощью очередей ожидания (wait queue). Очередь ожидания — это просто список процессов, которые ожидают наступления некоторого события. Очереди ожидания в ядре представляются с помощью типа данных wait_queue_head_t
. Они могут быть созданы статически с помощью макроса DECLARE_WAIT_QUEUE_HEAD()
или выделены динамически с последующей инициализацией с помощью функции init_waitqueue_head()
. Процессы помещают себя в очередь ожидания и устанавливают себя в приостановленное состояние. Когда происходит событие, связанное с очередью ожидания, процессы, находящиеся в этой очереди, возвращаются к выполнению. Важно реализовать переход в приостановленное состояние и возврат к выполнению правильно, так чтобы избежать конкуренции за ресурсы (race).