Введение в обработку прерываний
Отложенный вызов процедуры (Deferred Procedure Call, DPC)
Вдобавок к использованию для работы Диспетчера (планировщика) NT, IRQL dispatch_level также используется для обработки Отложенных Вызовов Процедур (DPC). Вызовы DPC – обратные вызовы подпрограмм, которые будут выполнены на IRQL dispatchjevel. Вызовы DPC обычно запрашиваются с более высоких уровней IRQL, для осуществления расширенной, не критической по времени обработки.
Давайте рассмотрим пару примеров того, когда используются DPC. Драйверы устройств Windows NT выполняют очень небольшую обработку внутри своих подпрограмм обслуживания прерывания. Вместо этого, когда устройство прерывается (на уровне DIRQL) и его драйвер определяет, что требуется сложная обработка, драйвер запрашивает DPC. Запрос DPC приводит к обратному вызову определенной функции драйвера на уровне IRQL dispatch_level для выполнения оставшейся части требуемой обработки. Выполняя эту обработку на IRQL dispatch_level, драйвер проводит меньшее количество времени на уровне DIRQL, и, следовательно, уменьшает время задержки прерывания для всех других устройств в системе.
На рисунке 15 изображена типовая последовательность событий.
Рис. 15. Определение Объекта DPC (KDPC)
Вначале ISR запрашивает DPC и NT помещает объект DPC в очередь целевого процессора. В зависимости от приоритета DPC и длины очереди DPC, NT генерирует программное прерывание DPC сразу же или спустя некоторое время. Когда процессор очищает очередь DPC, объект DPC покидает очередь и управление передается в его функцию DPC, завершающую обработку прерывания путем чтения данных из устройства или записи данных в устройство, сгенерировавшего прерывание.
Другое распространенное использование DPC – подпрограммы таймера. Драйвер может запросить выполнение конкретной функции для уведомления об истечении определенного периода времени (это делается путем использования функции KeSetTimer()). Программа обработки прерывания часов следит за прохождением времени, и, по истечении определенного периода времени, запрашивает DPC для подпрограммы, определенной драйвером. Использование DPC для таймерного уведомления позволяет программе обработки прерывания часов возвращаться быстро, но все же приводить к вызову указанной процедуры без чрезмерной задержки.