Я читал о прерываниях. Возможна приостановка некритических прерываний с помощью специальной маски прерывания. Это называется маскированием прерываний. Чего я не знаю, так это когда/почему вам может понадобиться временно приостановить прерывания? Возможно, семафоры или программирование в многопроцессорной среде?
Маскировка прерываний: зачем?
Ответы (4)
ОС делает это, когда готовится запустить свой собственный код «давайте организуем мир».
Например, в какой-то момент планировщик потоков ОС получает управление. Он подготавливает регистры процессора и все остальное, что необходимо сделать, прежде чем запустить поток, чтобы настроить среду для этого процесса и потока. Затем, прежде чем позволить этому потоку работать, он устанавливает прерывание таймера, которое будет вызвано после того, как истечет время, которое он намеревается позволить потоку иметь на ЦП.
По истечении этого периода времени (кванта) возникает прерывание, и планировщик ОС снова берет на себя управление. Он должен выяснить, что нужно делать дальше. Для этого ему необходимо сохранить состояние регистров процессора, чтобы он знал, как отменить побочные эффекты выполняемого кода. Если по какой-либо причине (например, какой-либо асинхронный ввод-вывод завершается) во время сохранения состояния возникает другое прерывание, это оставит ОС в ситуации, когда ее мир не находится в допустимом состоянии (фактически , сохранение состояния должно быть атомарной операцией).
Поэтому, чтобы не попасть в такую ситуацию, ядро ОС отключает прерывания, пока выполняются любые такие операции, которые должны быть атомарными. После того, как он сделал все, что нужно, и система снова находится в известном состоянии, он снова разрешает прерывания.
Раньше я программировал на плате ARM, которая могла вызвать около 10 прерываний. Каждая конкретная программа, которую я написал, никогда не интересовала более 4 из них. Например, на плате было 2 таймера, но мои программы использовали только 1. Я бы замаскировал прерывание второго таймера. Если бы я не замаскировал этот таймер, он мог бы быть включен и продолжать делать прерывания, которые замедляли бы мой код.
Другим примером было то, что я бы использовал прерывание UART по приему REGISTER full, и поэтому мне никогда не понадобилось прерывание UART по приему BUFFER full.
Я надеюсь, что это дало вам некоторое представление о том, почему вы можете захотеть отключить прерывания.
В дополнение к уже данным ответам, в этом есть элемент приоритета. Есть некоторые прерывания, которые вам нужны или вы хотите иметь возможность реагировать как можно быстрее, и другие, о которых вы хотели бы знать, но только тогда, когда вы не так заняты. Наиболее очевидным примером может быть перезаполнение буфера записи на устройстве записи DVD (где, если вы не сделаете этого вовремя, некоторые аппаратные средства просто запишут DVD неправильно) вместо обработки нового пакета из сети. Вы бы отключили прерывание для последнего при получении прерывания для первого и оставили бы его отключенным на время заполнения буфера.
На практике довольно много процессоров имеют приоритет прерывания, встроенный непосредственно в аппаратное обеспечение. Когда происходит прерывание, заблокированные флаги устанавливаются для меньших прерываний и часто это прерывание одновременно с чтением вектора прерывания и переходом на соответствующий адрес. Указание на получение прерывания также неявно маскирует это прерывание до тех пор, пока не закончится обработчик прерывания, что имеет приятный побочный эффект ослабления ограничений на аппаратное прерывание. Например. вы можете просто сказать, что высокий уровень сигнала запускает прерывание, и предоставить внешнему оборудованию решать, как долго оно хочет удерживать линию на высоком уровне, не беспокоясь о непреднамеренном запуске нескольких прерываний.
Во многих устаревших системах (включая z80 и 6502) существует только два уровня прерывания — маскируемое и немаскируемое, откуда, я думаю, и взялся язык включения или отключения прерываний. Но даже в оригинальном 68000 у вас есть восемь уровней прерывания и текущий уровень приоритета в ЦП, который определяет, какие уровни входящего прерывания действительно будут разрешены.
Представьте, что ваш ЦП сейчас находится в обработчике «int3», и в это время происходит «int2», а вновь возникший «int2» имеет более низкий приоритет по сравнению с «int3». Как бы мы поступили в этой ситуации?
Способ заключается в том, что при обработке «int3» мы маскируем другие прерыватели с более низким приоритетом. То есть мы видим, что «int2» сигнализирует ЦП, но ЦП не будет прерван им. После того, как мы закончили обработку "int3", мы делаем возврат из "int3" и демаскируем прерыватели с более низким приоритетом.
Место, куда мы вернулись, может быть:
- Другой процесс (в вытесняющей системе)
- Процесс, который был прерван "int3" (в системе без вытеснения или в системе с вытеснением)
- Обработчик int, который прерывается "int3", скажем, обработчик int1.
В случаях 1 и 2, поскольку мы демаскировали прерыватели с более низким приоритетом, а «int2» по-прежнему сигнализирует ЦП: «Привет, есть кое-что, что нужно обработать немедленно», тогда ЦП снова будет прерван, когда он выполняет инструкции. из процесса для обработки "int2"
В случае 3, если приоритет «int2» выше, чем «int1», тогда ЦП будет снова прерван, когда он выполняет инструкции от обработчика «int1», чтобы обработать «int2».
В противном случае обработчик «int1» выполняется без прерывания (поскольку мы также маскируем прерыватели с приоритетом ниже, чем «int1»), и ЦП вернется к процессу после обработки «int1» и демаскирует. В то время будет обрабатываться "int2".
c++
не очень актуален для вопроса? - person Cristian Ciupitu   schedule 07.02.2011