Первые две функции позволяют запретить указанную линию прерывания в контроллере прерываний. Это запрещает доставку данного прерывания всем процессорам в системе. Кроме того, функция disable_irq
не возвращается до тех пор, пока все обработчики прерываний, которые в данный момент выполняются, не закончат работу. Таким образом гарантируется не только то, что прерывания с данной линии не будут доставляться, но и то, что все выполняющиеся обработчики закончили работу. Функция disable_irq_nosync
не имеет последнего свойства.
Функция synchronize_irq
будет ожидать, пока не завершится указанный обработчик, если он, конечно, выполняется.
Вызовы этих функций должны быть сгруппированы, т.е. каждому вызову функции disable_irq
или disable_irq_nosync
должен соответствовать вызов функции enable_irq
. Только после последнего вызова функции enable_irq
линия запроса на прерывание будет снова разрешена. Например, если функция disable_irq
последовательно вызвана два раза, то линия запроса на прерывание не будет разрешена, пока функция enable_irq
тоже не будет вызвана два раза.
Эти три функции могут быть вызваны из контекста прерывания и из контекста процесса и не приводят к переходу в приостановленное состояние (sleep). При вызове из контекста прерывания следует быть осторожным! Например, нельзя разрешать линию прерывания во время выполнения обработчика прерывания (вспомним, что линия запроса на прерывание обработчика, который в данный момент выполняется, является замаскированной).
Было бы также плохим тоном запрещать линию прерывания, которая совместно используется несколькими обработчиками. Запрещение линии прерывания запрещает доставку прерываний для disable_irq
и дружественные ей обычно используются для устаревших устройств, таких как параллельный порт персонального компьютера.
Состояние системы обработки прерываний
Часто необходимо знать состояние системы обработки прерываний (например, прерывания запрещены или разрешены, выполняется ли текущий код в контексте прерывания или в контексте процесса).
Макрос irq_disabled
, который определен в файле
, возвращает ненулевое значение, если обработка прерываний на локальном процессоре запрещена. В противном случае возвращается нуль. Два следующих макроса позволяют определить контекст, в котором в данный момент выполняется ядро.
in_interrupt
in_irq
Наиболее полезный из них — это первый макрос. Он возвращает ненулевое значение, если ядро выполняется в контексте прерывания. Это включает выполнение как обработчика прерывания, так и обработчика нижней половины. Макрос in_irq
возвращает ненулевое значение, только если ядро выполняет обработчик прерывания.
Наиболее часто необходимо проверять, выполняется ли код в контексте процесса, т.е. необходимо проверить, что код выполняется не в контексте прерывания. Это требуется достаточно часто, когда коду необходимо выполнять что-то, что может быть выполнено только из контекста процесса, например переход в приостановленное состояние. Если макрос in_interrupt
возвращает нулевое значение, то ядро выполняется в контексте процесса.
Таблица 6.2. Список функций управления прерываниями