Разработка ядра Linux | страница 70
Первое изменение, внесенное для поддержки вытеснения пространства ядра, — это введение счетчика преемптивности >preempt_count
в структуру >thread_info
каждого процесса. Значение этого счетчика вначале равно нулю и увеличивается на единицу при каждом захвате блокировки, а также уменьшается на единицу при каждом освобождении блокировки. Когда значение счетчика равно нулю— ядро является вытесняемым. При возврате из обработчика прерывания, если возврат выполняется в пространство ядра, ядро проверяет значения переменных >need_resched
и >preempt_count
. Если флаг >need_resched
установлен и значение счетчика preempt_count равно нулю, значит, более важное задание готово к выполнению и выполнять вытеснение безопасно. Далее активизируется планировщик. Если значение счетчика >preempt_count
не равно нулю, значит, удерживается захваченная блокировка и выполнять вытеснение не безопасно. В таком случае возврат из обработчика прерывания происходит в текущее выполняющееся задание. Когда освобождаются все блокировки, удерживаемые текущим заданием, значение счетчика >preempt_count
становится равным нулю. При этом код, осуществляющий освобождение блокировки, проверяет, не установлен ли флаг >need_resched
. Если установлен, то активизируется планировщик. Иногда коду ядра необходимо иметь возможность запрещать или разрешать вытеснение в режиме ядра, что будет рассмотрено в главе 9.
Вытеснение пространства ядра также может произойти явно, когда задача блокируется в режиме ядра или явно вызывается функция >schedule()
. Такая форма преемптивности ядра всегда поддерживалась, так как в этом случае нет необходимости в дополнительной логике, которая бы давала возможность убедиться, что вытеснение проводить безопасно. Предполагается, что если код явно вызывает функцию >schedule()
, то точно известно, что перепланирование производить безопасно.
Вытеснение пространства ядра может произойти в следующих случаях.
• При возврате из обработчика прерывания в пространство ядра.
• Когда код ядра снова становится преемптивным.
• Если задача, работающая в режиме ядра, явно вызывает функцию >schedule()
.
• Если задача, работающая в режиме ядра, переходит в приостановленное состояние, т.е. блокируется (что приводит к вызову функции >schedule()
).
Режим реального времени
Операционная система Linux обеспечивает две стратегии планирования в режиме реального времени (real-lime): >SCHED_FIFO
и >SCHED_RR
. Стратегия планирования >SCHED_OTHER