DpcForIsr

DPC Target Processor

В дополнение к важности, каждый DPC Объект имеет целевой процессор (target processor). Это значение хранится в поле Number Объекта DPC. Целевой процессор показывает, ограничено ли выполнение DPC заданным процессором в системе, и, если да, то каким процессором. По умолчанию, KeInitializeDpc() не определяет целевой процессор. Следовательно, по умолчанию, DPC будут работать на процессоре, на котором они запрошены (то есть, DPC будет вызван на процессоре, на котором была вызвана подпрограмма KeInsertQueueDpc()).

DPC может быть ограничено выполнением на указанном процессоре, используя функцию KeSetTargetProcessorDpc(), прототип которой показан на Рисунке 6.8.

VOID

KeSetTargetProcessorDpc (IN PKDPC Dpc, IN CCHAR Number),

Dpc: Указывает на объект DPC, для которого должен быть установлен целевой процессор

Number: отсчитываемый от нуля номер процессора, на котором должен быть выполнен DPC.

Рисунок 6.8. Прототип функции KeSetTargetProcessorDpc().

Замечание.

Подобно важности DPC, целевой процессор DPC почти никогда не устанавливается драйвером устройства. Заданное по умолчанию значение, которое служит для выполнения DPC на текущем процессоре, почти всегда желательно.

Когда для Объекта DPC установлен конкретный целевой процессор, такой Объект DPC будет всегда ставиться в Очередь DPC указанного процессора. Таким образом, например, даже когда KeInsertQueueDpc() вызывается на процессоре 0, Объект DPC с установленным в качестве целевого процессора Процессором 1 будет вставлен в Очередь DPC Процессора 1.

Как уже обсуждалось в этой главе, наиболее часто DPC используются для завершения Программы Обработки Прерывания (ISR). Для того, чтобы упростить драйверам устройств запросы DPC для завершения ISR из их функций ISR, Диспетчер в/в определяет специальный DPC, который может использоваться для этой цели. Этот DPC называется DpcForIsr.

Диспетчер в/в вставляет Объект DPC в каждый Объект Устройство, который он создает. Этот внедренный Объект DPC инициализируется драйвером устройства, обычно при первой загрузке драйвера, посредством вызова функции IoInitializeDpcRequest() (см. Рисунок 13.18 и соответствующее описание в Главе 13).

IoInitializeDpcRequest() принимает на входе указатель на Объект Устройство, в который внедрен Объект DPC, указатель на функцию драйвера для вызова, и значение контекста для передачи этой функции. IoInitializeDpcRequest(), в свою очередь, вызывает KeInitializeDpc(), чтобы инициализировать внедренный Объект DPC, передавая указатель на функцию драйвера как параметр DeferredRoutme, и значение контекста как параметр DeferredContext.

Чтобы запросить DPC из ISR, драйвер просто вызывает IoRequestDpc() (см. Рисунок 13.2 и окружающий текст), передавая указатель на Объект Устройство. IoRequestDpc(), в свою очередь, вызывает KeInsertQueueDpc() для Объекта DPC, внедренного в Объект Устройство.

Поскольку все драйверы устройства имеют Объекты Устройство, и все драйверы, которые используют прерывания, также используют DPC, использование механизма DpcForIsr Диспетчера в/в очень удобно. Фактически, большинство драйверов устройств в Windows NT никогда напрямую не вызывают функции KeInitializeDpc() или KeInsertQueueDpc(), а вместо этого вызывают IoInitializeDpcRequest() и IoRequestDpc().


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: