Эти три функции могут быть вызваны из контекста прерывания и из контекста процесса и не приводят к переходу в приостановленное состояние (sleep). При вызове из контекста прерывания следует быть осторожным! Например, нельзя разрешать линию прерывания во время выполнения обработчика прерывания (вспомним, что линия запроса на прерывание обработчика, который в данный момент выполняется, является замаскированной).
Было бы также плохим тоном запрещать линию прерывания, которая совместно используется несколькими обработчиками. Запрещение линии прерывания запрещает доставку прерываний для всех устройств, которые используют эту линию. Поэтому в драйверах новых устройств не рекомендуется использовать эти интерфейсы [33] Многие старые устройства, в частности устройства ISA, не предоставляют возможности определить, являются ли они источником прерывания. Из-за этого линии прерывания для ISA-устройств часто не могут быть совместно используемыми. Поскольку спецификация шины PCI требует обязательной поддержки совместно используемых прерываний, современные устройства PCI поддерживают совместное использование прерываний. В современных компьютерах практически все линии прерываний могут быть совместно используемыми.
. Так как устройства PCI должны согласно спецификации поддерживать совместное использование линий прерываний, они вообще не должны использовать эти интерфейсы. Поэтому функция disable_irq()
и дружественные ей обычно используются для устаревших устройств, таких как параллельный порт персонального компьютера.
Состояние системы обработки прерываний
Часто необходимо знать состояние системы обработки прерываний (например, прерывания запрещены или разрешены, выполняется ли текущий код в контексте прерывания или в контексте процесса).
Макрос irq_disabled()
, который определен в файле , возвращает ненулевое значение, если обработка прерываний на локальном процессоре запрещена. В противном случае возвращается нуль. Два следующих макроса позволяют определить контекст, в котором в данный момент выполняется ядро.
in_interrupt()
in_irq()
Наиболее полезный из них — это первый макрос. Он возвращает ненулевое значение, если ядро выполняется в контексте прерывания. Это включает выполнение как обработчика прерывания, так и обработчика нижней половины. Макрос in_irq()
возвращает ненулевое значение, только если ядро выполняет обработчик прерывания.
Наиболее часто необходимо проверять, выполняется ли код в контексте процесса, т.е. необходимо проверить, что код выполняется не в контексте прерывания. Это требуется достаточно часто, когда коду необходимо выполнять что-то, что может быть выполнено только из контекста процесса, например переход в приостановленное состояние. Если макрос in_interrupt()
возвращает нулевое значение, то ядро выполняется в контексте процесса.
Таблица 6.2. Список функций управления прерываниями
Функция |
Описание |
local_irq_disable() |
Запретить доставку прерываний на локальном процессоре |
local_irq_enable() |
Разрешить доставку прерываний на локальном процессоре |
local_irq_save(unsigned long flags) |
Сохранить текущее состояние системы обработки прерываний на локальном процессоре и запретить прерывания |
local_irq_restore(unsigned long flags) |
Восстановить указанное состояние системы прерываний на локальном процессоре |
disable_irq(unsigned int irq) |
Запретить указанную линию прерывания с гарантией, что после возврата из этой функции не выполняется ни один обработчик данной линии |
disable_irq_nosync(unsigned int irq) |
Запретить указанную линию прерывания |
enable_irq(unsigned int irq) |
Разрешить указанную линию прерываний |
irqs_disabled() |
Возвратить ненулевое значение, если запрещена доставка прерываний на локальном процессоре, в противном случае возвращается нуль |
in_interrupt() |
Возвратить ненулевое значение, если выполнение производится в контексте прерывания, и нуль — если в контексте процесса |
in_irq() |
Возвратить ненулевое значение, если выполнение производится в контексте прерывания, и нуль — в противном случае |
Не нужно прерывать, мы почти закончили!
В этой главе были рассмотрены прерывания, аппаратные ресурсы, которые используются устройствами для подачи асинхронных сигналов процессору. Прерывания используются аппаратным обеспечением, чтобы прервать работу операционной системы.
Читать дальше