Введение
Сигнал, передаваемый процессору компьютера аппаратным или программным обеспечением.
В цифровых компьютерах прерывание (иногда называемое исключением) — это запрос к процессору прервать текущее выполнение кода (если это разрешено), чтобы событие могло быть обработано своевременно. Если запрос принят, процессор приостанавливает текущую деятельность, сохраняет свое состояние и выполняет функцию, называемую обработчиком прерывания (или подпрограммой обслуживания прерывания, ISR), для обработки события. Это прерывание часто является временным, позволяя программному обеспечению возобновить нормальную работу после завершения работы обработчика прерывания, хотя прерывание также может указывать на критическую ошибку. Прерывания обычно используются аппаратными устройствами для сигнализирования об электронных или физических изменениях состояния, требующих своевременного внимания. Прерывания также часто используются для реализации многозадачности и системных вызовов, особенно в системах реального времени. Системы, использующие прерывания таким образом, называются управляемыми прерываниями.
История
Аппаратные прерывания были введены как оптимизация, устраняя неэффективное время ожидания в циклах опроса при ожидании внешних событий. Первой системой, применившей этот подход, был DYSEAC, завершенный в 1954 году, хотя более ранние системы предоставляли функции обработки ошибок. Компьютер UNIVAC 1103A обычно считается первым, использовавшим прерывания в 1953 году.
Типы
Сигналы прерывания могут генерироваться в ответ на аппаратные или программные события. Они классифицируются как аппаратные прерывания или программные прерывания, соответственно. Для каждого конкретного процессора количество типов прерываний ограничено его архитектурой.
Прекращение работы оборудования
Аппаратное прерывание – это состояние, связанное с состоянием аппаратного обеспечения, которое может быть сигнализировано внешним аппаратным устройством, например, линией запроса прерывания (IRQ) на ПК, или обнаружено устройствами, встроенными в логику процессора (например, таймер процессора в IBM System/370), чтобы сообщить, что устройству требуется внимание операционной системы (ОС) или, при отсутствии ОС, программы, работающей непосредственно на процессоре. Такие внешние устройства могут быть частью компьютера (например, дисковый контроллер) или внешними периферийными устройствами. Например, нажатие клавиши на клавиатуре или перемещение мыши, подключенной к порту PS/2, генерирует аппаратные прерывания, которые заставляют процессор считать нажатую клавишу или положение мыши. Аппаратные прерывания могут поступать асинхронно относительно тактовой частоты процессора и в любой момент времени во время выполнения инструкции. Следовательно, все входящие сигналы аппаратных прерываний синхронизируются с тактовой частотой процессора и обрабатываются только на границах выполнения инструкций. Во многих системах каждое устройство связано с определенным сигналом IRQ. Это позволяет быстро определить, какое аппаратное устройство запрашивает обслуживание, и ускорить его обработку. В некоторых старых системах, таких как CDC 3600 1964 года, все прерывания направлялись в одно и то же место, и ОС использовала специализированную инструкцию для определения прерывания с наивысшим приоритетом, не заблокированного маской. В современных системах обычно существует отдельная подпрограмма обработки прерывания для каждого типа прерывания (или для каждого источника прерывания), часто реализованная в виде одной или нескольких таблиц векторов прерываний.
Отсутствующие прерывания
Одним из вариантов отказа является ситуация, когда аппаратное обеспечение не генерирует ожидаемое прерывание при изменении состояния, что приводит к бесконечному ожиданию операционной системы. В зависимости от конкретных обстоятельств, отказ может затронуть только один процесс или оказать глобальное воздействие. Некоторые операционные системы содержат специальный код для обработки подобных ситуаций. Например, операционная система IBM OS/360 (OS/360) ожидает прерывание "не готов – готов" от устройства после установки ленты в ленточный накопитель и не читает метку ленты, пока это прерывание не произойдет или не будет эмулировано. IBM добавила в OS/360 код, позволяющий команде VARY ONLINE эмулировать прерывание конца устройства на целевом устройстве.
Неправдоподобные перерывы
Ложный прерывание – это аппаратный прерывание, для которого не удается найти источник. Для описания этого явления также могут использоваться термины "фантомное прерывание" или "призрачное прерывание". Ложные прерывания чаще всего возникают в системах с проводной схемой ИЛИ, подключенной к входу процессора, чувствительному к уровню сигнала. Такие прерывания может быть сложно идентифицировать при некорректной работе системы. В схеме ИЛИ заряд и разряд паразитной емкости через подтягивающий резистор линии прерывания вызывают небольшую задержку перед тем, как процессор распознает, что источник прерывания был снят. Если устройство, вызвавшее прерывание, снимается слишком поздно в подпрограмме обработки прерывания (ISR), у схемы прерывания не будет достаточно времени для возврата в исходное состояние до завершения текущего экземпляра ISR. В результате процессор может ошибочно полагать, что другое прерывание находится в ожидании, поскольку напряжение на входе запроса прерывания не будет достаточно высоким или низким для установления однозначной внутренней логики 1 или 0. Кажущееся прерывание не будет иметь идентифицируемого источника, отсюда и название "ложное". Ложное прерывание также может быть вызвано электрическими аномалиями, обусловленными дефектами схемы, высоким уровнем помех, перекрестными наводками, проблемами с синхронизацией или, реже, ошибками в устройстве. Ложное прерывание может привести к взаимной блокировке системы или другим неопределенным операциям, если ISR не учитывает возможность его возникновения. Поскольку ложные прерывания в основном являются проблемой для схем ИЛИ, хорошей практикой программирования в таких системах является проверка ISR всех источников прерывания на предмет активности и отсутствие каких-либо действий (кроме возможной регистрации события), если ни один из источников не вызывает прерывание. В неблагоприятных сценариях они могут даже привести к сбою компьютера.
Прекращение работы программного обеспечения
Процессор запрашивает программное прерывание при выполнении определенных инструкций или при возникновении определенных условий. Каждый сигнал программного прерывания связан с конкретным обработчиком прерываний. Программное прерывание может быть вызвано намеренно путем выполнения специальной инструкции, которая по замыслу вызывает прерывание при выполнении. Такие инструкции функционируют аналогично вызовам подпрограмм и используются для различных целей, таких как запрос сервисов операционной системы и взаимодействие с драйверами устройств (например, для чтения или записи на носители информации). Программные прерывания также могут быть вызваны ошибками выполнения программы или системой виртуальной памяти. Как правило, ядро операционной системы перехватывает и обрабатывает такие прерывания. Некоторые прерывания обрабатываются прозрачно для программы – например, нормальное разрешение ошибки страницы заключается в обеспечении доступа к необходимой странице в физической памяти. Однако в других случаях, таких как ошибка сегментации, операционная система выполняет обратный вызов процесса. В Unix-подобных операционных системах это включает отправку сигнала, такого как SIGSEGV, SIGBUS, SIGILL или SIGFPE, который может вызвать обработчик сигнала или выполнить действие по умолчанию (завершение программы). В Windows обратный вызов осуществляется с помощью структурированной обработки исключений с кодом исключения, таким как STATUS_ACCESS_VIOLATION или STATUS_INTEGER_DIVIDE_BY_ZERO. В процессе ядра часто бывает, что некоторые типы программных прерываний не должны возникать. Если они все же возникают, может произойти сбой операционной системы.
Терминология
Термины прерывание, ловушка, исключение, ошибка и отмена используются для различения типов прерываний, хотя "нет чёткого консенсуса относительно точного значения этих терминов". Термин "ловушка" может относиться к любому прерыванию, любому программному прерыванию, любому синхронному программному прерыванию или только к прерываниям, вызванным инструкциями с "ловушкой" в их названии. В некоторых случаях термин "ловушка" относится конкретно к точке останова, предназначенной для инициирования переключения контекста на программу мониторинга или отладчик. Аппаратные прерывания – это прерывания, асинхронно вызываемые устройством ввода/вывода, позволяющие перезапустить программу без потери непрерывности. Ошибка также может быть перезапущена, но привязана к синхронному выполнению инструкции, при этом адрес возврата указывает на инструкцию, вызвавшую ошибку. Ловушка похожа на ошибку, за исключением того, что адрес возврата указывает на инструкцию, которая должна быть выполнена после инструкции-ловушки.
Arm использует термин "исключение" для обозначения всех типов прерываний и разделяет исключения на аппаратные прерывания, отмены, сброс и инструкции, генерирующие исключения. Отмены соответствуют исключениям x86 и могут быть отменами предварительной выборки (неудачная выборка инструкции) или отменами данных (неудачный доступ к данным), и могут быть синхронными или асинхронными. Асинхронные отмены могут быть точными или неточными. Отмены MMU (ошибки страниц) являются синхронными. RISC V использует термин "прерывание" как общий термин, а также для обозначения внешнего подмножества; внутренние прерывания называются исключениями.
Методы срабатывания
Каждый вход сигнала прерывания предназначен для срабатывания либо от уровня логического сигнала, либо от определенного фронта сигнала (изменения уровня). Входы, чувствительные к уровню, непрерывно запрашивают обслуживание процессора, пока на вход подается определенный (высокий или низкий) логический уровень. Входы, чувствительные к фронту, реагируют на фронты сигнала: определенный (восходящий или нисходящий) фронт приводит к фиксации запроса на обслуживание; процессор сбрасывает эту фиксацию при выполнении обработчика прерывания.
Уровень запускается
Запрос прерывания по уровню формируется путем удержания сигнала прерывания на определенном активном уровне (высоком или низком). Устройство инициирует прерывание по уровню, устанавливая сигнал на активный уровень и удерживая его там. Оно снимает сигнал, когда процессор дает соответствующую команду, обычно после обработки запроса устройства. Процессор опрашивает входной сигнал прерывания в течение каждого цикла выполнения инструкции. Процессор распознает запрос прерывания, если сигнал активен в момент опроса. Входы прерывания по уровню позволяют нескольким устройствам совместно использовать общий сигнал прерывания посредством логического ИЛИ. Процессор определяет, какие устройства запрашивают обслуживание. После обработки запроса устройства процессор может повторно выполнить опрос и, при необходимости, обработать запросы других устройств перед выходом из подпрограммы обработки прерывания (ISR).
С разъемом на краю
Прерывание по фронту – это прерывание, которое возникает при изменении уровня сигнала на линии прерывания, либо при спадающем фронте (с высокого на низкий), либо при нарастающем фронте (с низкого на высокий). Устройство, желающее запросить прерывание, формирует импульс на линии и затем возвращает линию в неактивное состояние. Если импульс слишком короткий для обнаружения при использовании опроса ввода-вывода, может потребоваться специальное аппаратное обеспечение для его регистрации. Ключевой особенностью прерывания по фронту является то, что для его возникновения необходим переход сигнала; например, если сигнал был высоким-низким-низким, сработает только одно прерывание по спадающему фронту, а последующий низкий уровень не вызовет дополнительных прерываний. Для возникновения следующего прерывания сигнал должен вернуться на высокий уровень и снова перейти в низкий. Это отличается от прерывания по уровню, где низкий уровень будет продолжать генерировать прерывания (если они разрешены), пока сигнал не вернется в высокий уровень. Компьютеры с прерываниями по фронту могут включать регистр прерываний, который сохраняет статус ожидающих прерываний. Системы с регистрами прерываний обычно также имеют регистры маскирования прерываний.
Общие IRQ
Несколько устройств могут совместно использовать одну линию прерывания, если это предусмотрено их конструкцией. Линия прерывания должна иметь подтягивающий или подтягивающий к земле резистор, чтобы в неактивном состоянии она переходила в свое неактивное (по умолчанию) состояние. Устройства сигнализируют о прерывании, кратковременно переводя линию в неактивное состояние, и отпускают линию (перестают активно управлять ею), когда прерывание не активно. Этот тип соединения также называют с открытым коллектором. Линия затем передает все импульсы, генерируемые всеми устройствами. (Это аналогично шнуру в некоторых автобусах и троллейбусах, за который любой пассажир может потянуть, чтобы сообщить водителю о запросе остановки.) Однако импульсы прерываний от разных устройств могут сливаться, если они происходят близко друг к другу по времени. Чтобы избежать потери прерываний, процессор должен реагировать на фронт импульса (например, на восходящий фронт, если линия подтянута к питанию и управляется низким уровнем). После обнаружения прерывания процессор должен проверить все устройства на предмет необходимости обслуживания. Прерывания, срабатывающие по фронту, не имеют проблем, присущих прерываниям, срабатывающим по уровню, при совместном использовании. Обслуживание устройства с низким приоритетом может быть произвольно отложено, в то время как прерывания от устройств с высоким приоритетом продолжают приниматься и обслуживаться. Если есть устройство, которое процессор не знает, как обслуживать, и которое может генерировать ложные прерывания, оно не будет мешать сигнализации прерываний других устройств. Однако прерывание, срабатывающее по фронту, может быть легко пропущено, например, когда прерывания замаскированы на определенный период времени, и если нет какого-либо аппаратного запорного устройства, которое регистрирует событие, его невозможно восстановить. Эта проблема вызывала множество "зависаний" в раннем компьютерном оборудовании, поскольку процессор не знал, что от него ожидается какое-либо действие. Более современное оборудование часто имеет один или несколько регистров статуса прерываний, которые фиксируют запросы на прерывание; правильно написанный код обработки прерываний, срабатывающих по фронту, может проверять эти регистры, чтобы гарантировать, что ни одно событие не будет пропущено. Старая архитектура Industry Standard Architecture (ISA) использует прерывания, срабатывающие по фронту, не требуя, чтобы устройства могли совместно использовать линии IRQ, но все основные материнские платы ISA включают подтягивающие резисторы на своих линиях IRQ, поэтому правильно работающие устройства ISA, совместно использующие линии IRQ, должны работать нормально. Параллельный порт также использует прерывания, срабатывающие по фронту. Многие старые устройства предполагают, что они имеют исключительное право использования линий IRQ, что делает их совместное использование электрически небезопасным. Существует три способа, которыми несколько устройств могут "совместно использовать одну и ту же линию". Первый – исключительное управление (переключение) или исключительное соединение (с контактами). Второй – через шину (все подключены к одной и той же линии и прослушивают ее): карты на шине должны знать, когда им следует передавать данные, а когда нет (например, шина ISA). Передача данных может быть инициирована двумя способами: с помощью накопительного запора или логических вентилей. Логические вентили ожидают непрерывного потока данных, который отслеживается на предмет ключевых сигналов. Накопители срабатывают только тогда, когда удаленная сторона возбуждает вентиль за пределами порогового значения, поэтому согласованная скорость не требуется. Каждый из них имеет свои преимущества с точки зрения скорости и расстояния. Триггер, как правило, представляет собой метод обнаружения возбуждения: восходящий фронт, нисходящий фронт, пороговое значение (осциллограф может запускаться по широкому спектру форм и условий). Запуск программных прерываний должен быть встроен в программное обеспечение (как в ОС, так и в приложение). Приложение на языке "C" имеет в заголовке таблицу триггеров (таблицу функций), о которой знают и используют как приложение, так и ОС, и которая не связана с аппаратным обеспечением. Однако не следует путать это с аппаратными прерываниями, которые сигнализируют процессору (процессор выполняет программное обеспечение из таблицы функций, аналогично программным прерываниям).
Трудности с обменом линиями прерывания
Несколько устройств, совместно использующих одну линию прерывания (любого типа генерации), выступают друг для друга как источники ложных прерываний. При большом количестве устройств на одной линии, нагрузка на обработку прерываний растёт пропорционально квадрату числа устройств. Поэтому предпочтительнее равномерно распределять устройства по доступным линиям прерываний. Нехватка линий прерываний является проблемой в устаревших системных конструкциях, где линии прерываний представляют собой отдельные физические проводники. Прерывания с передачей сообщений, где линия прерывания является виртуальной, предпочтительны в новых системных архитектурах (таких как PCI Express) и существенно смягчают эту проблему. Некоторые устройства с некачественным программным интерфейсом не предоставляют возможности определить, запросили ли они обслуживание. Они могут зависать или работать некорректно при обработке, когда в этом нет необходимости. Такие устройства не терпят ложных прерываний и, следовательно, не могут совместно использовать линию прерывания. Платы ISA, из-за часто дешёвой конструкции и производства, печально известны этой проблемой. Такие устройства становятся всё более редкими, поскольку аппаратная логика дешевеет, а новые системные архитектуры требуют совместного использования прерываний.
Гибридный
Некоторые системы используют гибридную схему формирования сигналов прерываний, реагирующую как на фронт, так и на уровень. Аппаратное обеспечение не только обнаруживает фронт, но и проверяет, что сигнал прерывания остаётся активным в течение определённого времени. Гибридные прерывания часто используются для входа NMI (немаскируемого прерывания). Поскольку NMI обычно сигнализируют о серьёзных или даже катастрофических системных событиях, надёжная реализация этого сигнала стремится удостовериться в его достоверности, проверяя, что он остаётся активным в течение определённого периода времени. Такой двухэтапный подход помогает предотвратить влияние ложных прерываний на систему.
Сигнализированные сообщения
Сигнальное прерывание сообщением не использует физическую линию прерывания. Вместо этого устройство сигнализирует о запросе на обслуживание, отправляя короткое сообщение по каналу связи, обычно компьютерной шине. Сообщение может быть типа, зарезервированного для прерываний, либо существовать как уже определенный тип, например, запись в память. Сигнальные прерывания сообщениями очень похожи на прерывания по фронту, поскольку прерывание представляет собой кратковременный сигнал, а не постоянное условие. Программное обеспечение обработки прерываний обрабатывает оба типа примерно одинаково. Обычно допускается объединение нескольких ожидающих сигнальных прерываний с одним и тем же сообщением (одной и той же виртуальной линией прерывания), как и близко расположенные прерывания по фронту. Векторы сигнальных прерываний сообщениями могут совместно использоваться в той мере, в которой это позволяет совместное использование базового канала связи. Дополнительных усилий не требуется. Поскольку идентификация прерывания указывается шаблоном битов данных, а не требует отдельного физического проводника, можно эффективно обрабатывать значительно больше различных прерываний. Это снижает необходимость совместного использования ресурсов. Прерывающие сообщения также могут передаваться по последовательной шине, не требуя дополнительных линий. PCI Express, последовательная компьютерная шина, использует исключительно сигнальные прерывания сообщениями.
Звонок в дверь
В аналогии с кнопкой, применяемой к компьютерным системам, термин "звонок в дверь" или "прерывание по звонку в дверь" часто используется для описания механизма, посредством которого программная система может сигнализировать или уведомлять компьютерное аппаратное устройство о необходимости выполнения какой-либо задачи. Обычно программная система помещает данные в заранее известные и согласованные области памяти и "подает сигнал" (или "звонит в дверной звонок"), записывая в другую область памяти. Эта область памяти часто называется областью дверного звонка, и в ней может быть несколько "звонков", предназначенных для разных целей. Именно запись в область памяти дверного звонка "активирует сигнал" и уведомляет аппаратное устройство о готовности данных. Аппаратное устройство теперь знает, что данные действительны и могут быть обработаны. Обычно оно записывает данные на жесткий диск, отправляет их по сети, шифрует их и т.д. Термин "прерывание по звонку в дверь" часто является неточным. Он похож на прерывание, поскольку заставляет устройство выполнить определенную работу; однако область дверного звонка иногда реализуется как опрашиваемая область, иногда запись в область дверного звонка осуществляется непосредственно в физические регистры устройства, а иногда область дверного звонка напрямую подключена к физическим регистрам устройства. При записи через или непосредственно в физические регистры устройства это может вызвать реальное прерывание в центральном процессоре (CPU) устройства, если он имеется. "Прерывания по звонку в дверь" можно сравнить с прерываниями, сигнализируемыми сообщениями, поскольку они имеют некоторые общие черты.
IPI многопроцессора
В многопроцессорных системах процессор может отправлять запрос на прерывание другому процессору посредством межпроцессорных прерываний (IPI).
Выступление
Перерывы обеспечивают низкие накладные расходы и хорошую задержку при низкой нагрузке, но значительно ухудшаются при высокой частоте прерываний, если не предпринять мер для предотвращения ряда проблем. Феномен, при котором общая производительность системы серьезно снижается из-за чрезмерного времени, затрачиваемого на обработку прерываний, называется "штормом прерываний". Существуют различные формы взаимных блокировок (livelocks), когда система тратит все свое время на обработку прерываний в ущерб другим необходимым задачам. В экстремальных условиях большое количество прерываний (например, при очень высоком сетевом трафике) может полностью остановить систему. Чтобы избежать таких проблем, операционная система должна планировать обработку сетевых прерываний так же тщательно, как и выполнение процессов. При использовании многоядерных процессоров дополнительное повышение производительности обработки прерываний можно достичь с помощью масштабирования на стороне приема (RSS) при использовании сетевых карт с несколькими очередями (multiqueue NICs). Такие сетевые карты предоставляют несколько очередей приема, связанных с отдельными прерываниями; направляя каждое из этих прерываний на разные ядра, обработка запросов прерываний, вызванных сетевым трафиком, получаемым одной сетевой картой, может быть распределена между несколькими ядрами. Распределение прерываний между ядрами может выполняться автоматически операционной системой, либо маршрутизация прерываний (обычно называемая IRQ affinity) может быть настроена вручную. Полностью программная реализация распределения входящего трафика, известная как управление пакетами приема (RPS), распределяет полученный трафик между ядрами на более позднем этапе обработки данных, как часть функциональности обработчика прерываний. Преимущества RPS по сравнению с RSS включают отсутствие требований к конкретному оборудованию, более продвинутые фильтры распределения трафика и снижение частоты прерываний, генерируемых сетевой картой. Недостатком RPS является увеличение частоты межпроцессорных прерываний (IPI). Управление потоком приема (RFS) развивает программный подход, учитывая локальность приложений; дальнейшее повышение производительности достигается за счет обработки запросов прерываний теми же ядрами, на которых целевое приложение будет потреблять конкретные сетевые пакеты.
Типичные применения
Перерывания обычно используются для обслуживания аппаратных таймеров, передачи данных в хранилище (например, ввода-вывода с диска) и коммуникационных интерфейсов (например, UART, Ethernet), обработки событий клавиатуры и мыши и реагирования на любые другие события, критичные ко времени, в соответствии с требованиями прикладной системы. Немаскируемые прерывания обычно используются для реагирования на запросы высокого приоритета, такие как истечение времени ожидания сторожевого таймера, сигналы отключения питания и исключения. Аппаратные таймеры часто используются для генерации периодических прерываний. В некоторых приложениях такие прерывания подсчитываются обработчиком прерываний для отслеживания абсолютного или прошедшего времени, или используются планировщиком задач ОС для управления выполнением запущенных процессов, или и то, и другое. Периодические прерывания также обычно используются для инициирования выборки данных с входных устройств, таких как аналого-цифровые преобразователи, интерфейсы инкрементальных энкодеров и GPIO-входы, а также для программирования выходных устройств, таких как цифро-аналоговые преобразователи, контроллеры двигателей и GPIO-выходы. Прерывание диска сигнализирует о завершении передачи данных на диск или с диска; это может привести к запуску процесса, ожидающего чтения или записи. Прерывание отключения питания предсказывает неминуемую потерю питания, позволяя компьютеру выполнить упорядоченное завершение работы, пока еще остается достаточно энергии для этого. Прерывания клавиатуры обычно приводят к буферизации нажатий клавиш для реализации предвводного набора текста. Прерывания иногда используются для эмуляции инструкций, которые не реализованы на некоторых компьютерах в продуктовой линейке. Например, инструкции с плавающей запятой могут быть реализованы аппаратно в одних системах и эмулированы в более дешевых системах. В последнем случае выполнение нереализованной инструкции с плавающей запятой вызовет исключение "недопустимая инструкция". Обработчик прерывания реализует функцию с плавающей запятой программно, а затем возвращается к прерванной программе, как если бы аппаратная инструкция была выполнена. Это обеспечивает переносимость прикладного программного обеспечения по всей линейке продуктов. Прерывания похожи на сигналы, разница заключается в том, что сигналы используются для межпроцессного взаимодействия (IPC), опосредованного ядром (возможно, через системные вызовы) и обрабатываемого процессами, в то время как прерывания опосредованы процессором и обрабатываются ядром. Ядро может передать прерывание в качестве сигнала процессу, который его вызвал (типичные примеры: SIGSEGV, SIGBUS, SIGILL и SIGFPE).