Основная функция прерываний в компьютере заключается в том, чтобы позволить взаимодействовать периферийным устройствам с процессором, информируя его о завершении работы задачи, ошибочных состояниях и других событиях, требующих немедленного внимания. Прерывания происходят независимо от текущих действий системы или какого-либо процесса. Это означает, что система не знает заранее, в каком месте выполнения потока инструкций может произойти прерывание. Функция, запускаемая для обслуживания прерывания, называется обработчиком прерывания, или процедурой обслуживания прерывания. Обработчик работает в режиме ядра и системном контексте. Так как прерванный процесс обычно не имеет никакого отношения к произошедшему в системе прерыванию, обработчик не должен обращаться к контексту процесса. По той же причине он также не обладает правом блокировки.
Однако прерывание оказывает некоторое влияние на выполнение текущего процесса. Время, потраченное на обработку прерывания, является частью кванта времени, отведенного процессу, даже если производимые действия не имеют ни малейшего к нему отношения. Так, обработчик прерываний системного таймера использует тики (промежутки времени между двумя прерываниями таймера) текущего процесса и потому нуждается в доступе к его структуре ргос. Важно отметить, что контекст процесса защищен от доступа обработчиками прерываний не полностью. Неверно написанный обработчик может причинить вред любой части адресного пространства процесса.
Ядро также поддерживает программные или системные прерывания, которые могут генерироваться при выполнении специальных инструкций. Такие прерывания могут использоваться, к примеру, в переключателе контекстов или в планировании задач, функционирующих в режиме разделения времени и имеющих низкий приоритет. Несмотря на то что описанные прерывания происходят синхронно с нормальной работой системы, они обрабатываются точно так же, как и обычные. Вследствие того что причиной возникновения прерываний может стать множество различных событий, представима и такая ситуация, когда прерывание происходит во время того, как обрабатывается другое. Перед разработчиками системы UNIX встала необходимость поддержки различных уровней приоритетов, для того чтобы прерывания более высокого уровня обслуживались раньше, чем прерывания более низких уровней. К примеру, прерывание аппаратного таймера должно обслуживаться раньше прерывания сети, так как последнее может потребовать больших объемов вычислений в течение нескольких тиков системного таймера.
В системах UNIX каждому типу прерывания принято назначать уровень приоритета прерывания (interrupt priority level, ipl). В первых реализациях системы уровень ipl находился в пределах от 0 до 7. В ОС BSD значение ipl возросло до 0-31. Регистр состояния процессора обычно содержит битовые поля, в которых хранится текущий (а иногда и предыдущий) ipl1. Номера приоритетов прерываний не одинаковы, так как зависят не только от конкретной реализации системы UNIX, но и от различия в архитектуре.
Некоторые процессоры, например Intel 80x86, не поддерживают приоритеты прерываний на аппаратном уровне. В таких системах необходимо реализовывать уровни ipl программно. Эта проблема будет затронута в дальнейшем в упражнениях. дования. В некоторых системах ipl 0 означает низший уровень приоритета, тогда как в иных это значение может оказаться наивысшим. Для облегчения создания процедур обработки прерываний и драйверов устройств в системах UNIX представлен набор триггеров для блокировки и разблокирования прерываний. Однако в различных реализациях системы для одних и тех же целей используются различные триггеры. В табл. 2.1 показаны некоторые триггеры, применяемые в 4.3BSD и SVR4.
После того как в системе происходит прерывание, дальнейшие действия зависят от его уровня: если уровень ipl окажется выше текущего, то действия приостанавливаются, и запускается обработчик уже нового прерывания. Обработчик начинает свою работу на новом уровне ipl. После завершения процедуры обслуживания прерывания уровень ipl понижается до предыдущего значения (которое хранится в предыдущем слове состояния процессора в стеке прерываний), и ядро продолжает обработку текущего прерванного процесса. Если ядро получает прерывание, имеющее уровень более низкий или равный текущему значению ipl, то такое прерывание не будет обрабатываться незамедлительно. Оно будет сохранено в регистре прерываний и обработано после соответствующего изменения уровня ipl. Алгоритм обработки прерываний показан на рис. 2.5. Уровни ipl сравниваются и устанавливаются на аппаратном уровне в зависимости от архитектуры конкретного компьютера. Ядро системы UNIX имеет механизмы четкого определения или установки уровней ipl. К примеру, ядро может повысить уровень ipl с целью блокировки прерываний на время выполнения некоторых критичных инструкций. Подробнее об этой возможности см. в разделе 2.5.2. На некоторых аппаратных платформах поддерживается возможность организации отдельного глобального стека прерываний, используемого всеми обработчиками. На платформах, не имеющих подобного стека, обработчики
задействуют стек ядра текущего процесса. В таком случае должен быть обеспечен механизм изоляции остальной части стека ядра от обработчика. Для этого ядро помещает в свой стек уровень контекста перед вызовом обработчика. Этот уровень контекста, подобно кадру стека, содержит в себе информацию, необходимую для восстановления контекста выполнения, предшествующего вызову обработчика прерывания.
Несомненно, после долгой и продолжительной работы за компьютером нужно отдохнуть. Как вариант неплохо подходят анапа витязево отели