DPC (DPC)
DPC (англ. Deferred procedure call — отложенный вызов процедуры) — специфический механизм вызова процедур в архитектуре Windows.
Суть DPC
[править | править код]При возникновении прерывания управление передаётся обработчику прерывания. Существует ряд факторов, ограничивающих возможности кода обработчика прерывания:
- Общей практикой является требование минимизации времени работы обработчика прерывания. Поэтому необходимо воздержаться от выполнения ресурсоёмких и долгих действий непосредственно внутри обработчика прерывания.
- В Windows код обработчика прерывания выполняется на высоком IRQL, что сильно ограничивает набор доступных обработчику функций ядра: многие функции требуют гораздо более низкого IRQL для своего вызова.
Решением этой проблемы является подход, при котором непосредственно в обработчике выполняются лишь самые критические операции, а остальные действия откладываются до тех пор, пока не появится относительно свободное процессорное время, а IRQL не опустится до допустимого значения (DISPATCH_LEVEL
). Тогда эти действия будут выполнены в рамках вызова отложенной (её выполнение было отложено до этого момента) процедуры.
В отличие от обычного вызова процедуры, при котором, фактически, управление сразу же передаётся коду вызываемой процедуры, при DPC-вызове передачи управления вызываемой процедуре не происходит — вместо этого адрес вызываемой процедуры и параметры помещаются в специальную очередь[1], называемую DPC Queue. Когда наступает «благоприятное» время, отложенная процедура вызывается по-настоящему.
Таким образом, обработчик прерывания выполняет только самые необходимые действия и осуществляет отложенный вызов процедуры, которая выполнит все остальные действия, нужные в рамках обработки прерывания, но не требующие повышенной срочности.
Управление DPC
[править | править код]- Для того, чтобы осуществлять отложенные вызовы, необходимо сперва создать объект DPC при помощи функции ядра KeInitializeDpc.
- Созданному объекту DPC можно изменить приоритет при помощи функции KeSetImportanceDpc, а также переназначить логический процессор, в очередь которого будет помещён отложенный вызов, с помощью KeSetTargetProcessorDpc.
- Постановка DPC в очередь осуществляется вызовом функции ядра KeInsertQueueDpc.
- Помещённый в очередь DPC можно убрать из очереди вызовом функции KeRemoveQueueDpc.
Поскольку механизм DPC используется главным образом в рамках обработки запросов ввода-вывода, существуют специальные функции-обёртки с префиксом Io
для управления отложенными вызовами. В частности, обработчики прерываний, согласно документации, должны использовать именно эти функции.
Примечания
[править | править код]- ↑ В многопроцессорных системах каждый процессор имеет свою отдельную очередь отложенных вызовов. Так что каждый отложенный вызов ассоциирован с определённым процессором.
См. также
[править | править код]Литература
[править | править код]- М. Руссинович, Д. Соломон. 1 // Внутреннее устройство Microsoft Windows. — 6-е изд.. — СПб.: Питер, 2013. — С. 131—138. — 800 с. — ("Мастер-класс"). — ISBN 978-5-459-01730-4.
- Уолтер Они. Использование Microsoft Windows Driver Model. — 2-е изд.. — СПб.: Питер, 2007. — С. 236. — 764 с. — ISBN 978-5-91180-057-4.
- Art Baker & Jerry Lozano. Windows® 2000 Device Driver Book: A Guide for Programmers, Second Edition, The (англ.). — Prentice Hall., 2000. — ISBN 978-0-13-020431-8. (недоступная ссылка)
- Microsoft tech article on DPC (англ.)
- Microsoft definition of DPC (англ.)