Маскировка прерываний: зачем?

Я читал о прерываниях. Возможна приостановка некритических прерываний с помощью специальной маски прерывания. Это называется маскированием прерываний. Чего я не знаю, так это когда/почему вам может понадобиться временно приостановить прерывания? Возможно, семафоры или программирование в многопроцессорной среде?


person Community    schedule 07.02.2011    source источник
comment
мое ограниченное понимание заключается в том, что обычно вы хотите делать это внутри критических разделов кода драйвера, чтобы гарантировать, что атомарная операция не будет прервана.   -  person SpliFF    schedule 07.02.2011
comment
Это мне или тег c++ не очень актуален для вопроса?   -  person Cristian Ciupitu    schedule 07.02.2011
comment
@Cristian Ciupitu: согласен. В любом случае, это больше связано с операционными системами. Сменить тег.   -  person MSalters    schedule 07.02.2011


Ответы (4)


ОС делает это, когда готовится запустить свой собственный код «давайте организуем мир».

Например, в какой-то момент планировщик потоков ОС получает управление. Он подготавливает регистры процессора и все остальное, что необходимо сделать, прежде чем запустить поток, чтобы настроить среду для этого процесса и потока. Затем, прежде чем позволить этому потоку работать, он устанавливает прерывание таймера, которое будет вызвано после того, как истечет время, которое он намеревается позволить потоку иметь на ЦП.

По истечении этого периода времени (кванта) возникает прерывание, и планировщик ОС снова берет на себя управление. Он должен выяснить, что нужно делать дальше. Для этого ему необходимо сохранить состояние регистров процессора, чтобы он знал, как отменить побочные эффекты выполняемого кода. Если по какой-либо причине (например, какой-либо асинхронный ввод-вывод завершается) во время сохранения состояния возникает другое прерывание, это оставит ОС в ситуации, когда ее мир не находится в допустимом состоянии (фактически , сохранение состояния должно быть атомарной операцией).

Поэтому, чтобы не попасть в такую ​​ситуацию, ядро ​​ОС отключает прерывания, пока выполняются любые такие операции, которые должны быть атомарными. После того, как он сделал все, что нужно, и система снова находится в известном состоянии, он снова разрешает прерывания.

person Jon    schedule 07.02.2011
comment
В большинстве современных операционных систем используются обработчики прерываний с повторным входом, которые спроектированы таким образом, что они не повреждают существующее состояние независимо от того, сколько возникает вложенных прерываний, поэтому ситуация недопустимого состояния не возникает. Как ответил @Tommy, приоритеты являются основной причиной использования маскировки. - person casablanca; 07.02.2011
comment
В этом ответе обсуждается отключение прерываний (т.е. глобальное маскирование). Он не решает первоначальный вопрос о приостановке некритических прерываний через специальную маску прерывания. - person D Krueger; 07.02.2011
comment
Википедия говорит, что глобальные маски прерываний имеют много проблем, включая остановку мира в многопроцессорных системах и дрейф часов. Используются ли глобальные маски прерываний в однопроцессорных и многопроцессорных ситуациях для таких ОС, как Linux/Windows/BSD? - person CMCDragonkai; 27.06.2016
comment
Keil RTX не блокирует прерывания во всей области работы ядра, интересно, как это реализуется - person Chen; 23.11.2017

Раньше я программировал на плате ARM, которая могла вызвать около 10 прерываний. Каждая конкретная программа, которую я написал, никогда не интересовала более 4 из них. Например, на плате было 2 таймера, но мои программы использовали только 1. Я бы замаскировал прерывание второго таймера. Если бы я не замаскировал этот таймер, он мог бы быть включен и продолжать делать прерывания, которые замедляли бы мой код.

Другим примером было то, что я бы использовал прерывание UART по приему REGISTER full, и поэтому мне никогда не понадобилось прерывание UART по приему BUFFER full.

Я надеюсь, что это дало вам некоторое представление о том, почему вы можете захотеть отключить прерывания.

person WuHoUnited    schedule 07.02.2011
comment
Спасибо, что поделились примерами программирования из реального мира. - person ; 07.02.2011

В дополнение к уже данным ответам, в этом есть элемент приоритета. Есть некоторые прерывания, которые вам нужны или вы хотите иметь возможность реагировать как можно быстрее, и другие, о которых вы хотели бы знать, но только тогда, когда вы не так заняты. Наиболее очевидным примером может быть перезаполнение буфера записи на устройстве записи DVD (где, если вы не сделаете этого вовремя, некоторые аппаратные средства просто запишут DVD неправильно) вместо обработки нового пакета из сети. Вы бы отключили прерывание для последнего при получении прерывания для первого и оставили бы его отключенным на время заполнения буфера.

На практике довольно много процессоров имеют приоритет прерывания, встроенный непосредственно в аппаратное обеспечение. Когда происходит прерывание, заблокированные флаги устанавливаются для меньших прерываний и часто это прерывание одновременно с чтением вектора прерывания и переходом на соответствующий адрес. Указание на получение прерывания также неявно маскирует это прерывание до тех пор, пока не закончится обработчик прерывания, что имеет приятный побочный эффект ослабления ограничений на аппаратное прерывание. Например. вы можете просто сказать, что высокий уровень сигнала запускает прерывание, и предоставить внешнему оборудованию решать, как долго оно хочет удерживать линию на высоком уровне, не беспокоясь о непреднамеренном запуске нескольких прерываний.

Во многих устаревших системах (включая z80 и 6502) существует только два уровня прерывания — маскируемое и немаскируемое, откуда, я думаю, и взялся язык включения или отключения прерываний. Но даже в оригинальном 68000 у вас есть восемь уровней прерывания и текущий уровень приоритета в ЦП, который определяет, какие уровни входящего прерывания действительно будут разрешены.

person Tommy    schedule 07.02.2011
comment
+1 за упоминание приоритетов. Я только что написал об этом, удивляясь, почему никто еще не упомянул об этом. - person casablanca; 07.02.2011
comment
Если прерывание отключено, оно просто игнорируется и отбрасывается или каким-то образом ставится в очередь? - person CMCDragonkai; 27.06.2016
comment
@CMCDragonkai зависит от архитектуры и прерывающего устройства — некоторые прерывания сигнализируют в течение определенного периода времени, а затем автоматически разрешаются независимо от того, действует ЦП или нет, вероятно, большинство продолжают утверждать, пока ЦП не справится с ними. Обычно это зависит от того, что они пытаются сообщить. - person Tommy; 28.06.2016

Представьте, что ваш ЦП сейчас находится в обработчике «int3», и в это время происходит «int2», а вновь возникший «int2» имеет более низкий приоритет по сравнению с «int3». Как бы мы поступили в этой ситуации?

Способ заключается в том, что при обработке «int3» мы маскируем другие прерыватели с более низким приоритетом. То есть мы видим, что «int2» сигнализирует ЦП, но ЦП не будет прерван им. После того, как мы закончили обработку "int3", мы делаем возврат из "int3" и демаскируем прерыватели с более низким приоритетом.

Место, куда мы вернулись, может быть:

  1. Другой процесс (в вытесняющей системе)
  2. Процесс, который был прерван "int3" (в системе без вытеснения или в системе с вытеснением)
  3. Обработчик int, который прерывается "int3", скажем, обработчик int1.

В случаях 1 и 2, поскольку мы демаскировали прерыватели с более низким приоритетом, а «int2» по-прежнему сигнализирует ЦП: «Привет, есть кое-что, что нужно обработать немедленно», тогда ЦП снова будет прерван, когда он выполняет инструкции. из процесса для обработки "int2"

В случае 3, если приоритет «int2» выше, чем «int1», тогда ЦП будет снова прерван, когда он выполняет инструкции от обработчика «int1», чтобы обработать «int2».

В противном случае обработчик «int1» выполняется без прерывания (поскольку мы также маскируем прерыватели с приоритетом ниже, чем «int1»), и ЦП вернется к процессу после обработки «int1» и демаскирует. В то время будет обрабатываться "int2".

person user4378998    schedule 19.12.2014