Программирование драйверов Windows


Особенности механизма DPC - часть 2


Если присмотреться к списку параметров вызовов IoInitializeDpcRequest

и IoRequestDpc (предназначенных для работы с DpcForIsr процедурами), то нетрудно заметить, что DPC объект "привязан" к объекту устройства. При размещении этого объекта в DPC очереди в момент работы ISR процедуры также указывается объект устройства. Этим и достигается определенность, вызов какой конкретно DPC процедуры "заказан" ISR процедурой (соотнесение по объекту устройства). Это же говорит о том, что драйвер, который создал несколько объектов устройств (достаточно редкий случай), может эксплуатировать и несколько процедур DpcForIsr &#8212 по одной для каждого объекта устройства.

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

Выше было рассмотрено использование DPC процедур для завершения обработки прерываний, то есть DpcForIsr. Однако DPC процедуры можно использовать и в другом ключе, например, совместно с таймерами для организации ожидания. Для этого создастся объект DPC при помощи вызова KeInitializeDPC, который связывает этот объект с DPC процедурой, входящей в состав драйвера. После этого можно выполнять установку времени ожидания в предварительно инициализированном (используя KeInitializeTimer или KeInitializeEx) объекте таймера. Для установки интервала ожидания используется вызов KeSetTimer, которому в качестве одного из параметров необходимо передать указатель на инициализированный DPC объект. Пo истечении интервала ожидания DPC объект будет внесен в системную DPC очередь, и DPC процедура, ассоциированная с ним, будет вызвана так скоро, насколько этo будет возможно. Процедуры DPC данного, второго, типа обозначены в документации DDK термином 'Custom DPC'. (Этот вариант использования DPC процедур делает их весьма напоминающими APC вызовы пользовательского режима.)

Для размещения в системной DPC очереди объектов, соответствующих второму типу DPC процедур (не связанных с прерываниями), следует использовать вызов KeInsertQueueDpc. Соответственно, код-инициатор вызова должен работать на уровне IRQL не ниже DISPATCH_LEVEL.

Для очистки системной DPC очереди от Custom DPC процедур, например, если драйвер должен срочно завершить работу, предназначен вызов KeRemoveQueueDpc, который может быть вызван из кода любого уровня IRQL.




Начало  Назад  Вперед