Разделение времени и данных с ISR процедурой
Вместо вызовов InterlockedXxx, примененных выше для синхронизации доступа к счетчику вызовов MyIoTimerRoutine, можно применить следующий метод, который пригоден всегда, когда нужно гарантировать, что в некую работу над некими данными не вмешается неожиданно процедура обработки прерываний, работающая, как правило, с максимальным для конкретного драйвера приоритетом.
Для выполнения такой работы (например, модификации совместно используемых данных из низкоприоритетной процедуры) создается обособленная функция IsrRoutineConcurrent по прототипу, описанному в таблице 10.13.
Таблица 10.13. Прототип функции IsrRoutineConcurrent
BOOLEAN IsrRoutineConcurrent | IRQL == см. ниже | |
Параметры | Манипуляции на уровне IRQL прерывания | |
IN PVOID pContext | Контекстный указатель | |
Возвращаемое значение | TRUE — в случае успешного завершения (с точки зрения разработчика драйвера) или FALSE |
При необходимости выполнить некоторую работу, которая не может быть прервана функцией обработки прерывания, следует выполнить вызов KeSynchronizeExecution, см. таблицу 10.14.
Вызов KeSynchronizeExecution повышает уровень IRQL до значения SynchronizeIrql, указанного при создании объекта прерывания pInterruptObj системным вызовом IoConnectInterrupt, см. таблицу 8.10, в результате чего с данным объектом прерывания оказалась связана ISR процедура драйвера. Кроме того, данный вызов получает доступ к объекту спин-блокировки, связанному с данным объектом прерывания. В результате доступ к данным по контекстному указателю pContext становится безопасным в том смысле, что другие низкоприоритетные процедуры драйвера просто не могут работать в это время, так же, как не может стартовать и процедура обработки прерывания (если, разумеется, значения Irql и SynchronizeIrql равны, таблица 8.10). В том случае, если Irql превышает SynchronizeIrql, то доступ по указателю pContext из функции IsrRoutineConcurrent остается безопасным по причине владения упомянутым объектом спин-блокировки.
Таблица 10.14. Прототип вызова KeSynchronizeExecution