Прочитать на английском

Поделиться через


Использование процедуры CustomTimerDpc

Чтобы отключить ранее заданный объект таймера, драйвер вызывает KeCancelTimer. Эта подпрограмма удаляет объект таймера из очереди таймера системы. Как правило, объект таймера не задан для сигнального состояния, и подпрограмма CustomTimerDpc не помещается в очередь для выполнения. Однако если таймер скоро истекает, когда вызывается KeCancelTimer, таймер может сработать до того, как KeCancelTimer имеет возможность получить доступ к очереди таймеров, в этом случае будет выполнено сигнализирование и постановка в очередь DPC.

Отзыв KeSetTimer или KeSetTimerEx с ранее заданными указателями таймера и Dpc до истечения заданного интервала имеет следующие эффекты:

  • Ядро удаляет объект таймера из очереди таймера, не устанавливая объект в сигнальное состояние и не ставя в очередь подпрограмму CustomTimerDpc.

  • Ядро повторно встраивает объект таймера в очередь таймера, используя новое значение DueTime .

Использование одного и того же объекта таймера для различных целей может привести к проблемам гонки или серьезным ошибкам водителя. Например, предположим, что драйвер задает один объект таймера как для настройки вызова подпрограммы CustomTimerDpc , так и для настройки ожиданий в выделенном драйвере потоке. Всякий раз, когда выделенный драйвером поток вызывает KeSetTimer, KeSetTimerEx или KeCancelTimer для общего объекта таймера, поток отменит вызовы подпрограммы CustomTimerDpc, если объект таймера уже был поставлен в очередь для вызова CustomTimerDpc.

Если драйвер имеет подпрограммы CustomTimerDpc , а также ожидает объектов таймера в контексте непарбитрного потока, он должен:

  • Никогда не используйте объект таймера с учетом контекста потока в контексте непарбитарных потоков или наоборот.

  • Выделите отдельный объект таймера для каждой подпрограммы CustomTimerDpc . Каждый набор потоков драйверов или подпрограмм драйверов, вызываемых в контексте непарбитрарного потока, должен иметь собственный набор объектов таймера ожидания.

Если вы используете подпрограмму CustomTimerDpc, тщательно выберите интервал, который драйвер передает в вызовах KeSetTimer или KeSetTimerEx. Кроме того, рассмотрите все возможные последствия вызова KeCancelTimer с одним и тем же объектом таймера из любой подпрограммы драйвера, которая делает этот вызов, особенно на платформах SMP.

Помните следующее о подпрограммах CustomTimerDpc :

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

Если второй подпрограмма драйвера вызывает KeSetTimer или KeSetTimerEx для выполнения той же подпрограммы CustomTimerDpc до истечения срока действия интервала, указанного первым вызывающим оператором, подпрограмма CustomTimerDpc выполняется только после истечения срока действия второго вызывающего объекта. В этих обстоятельствах CustomTimerDpc не выполняет никаких действий, для которых первая подпрограмма называется KeSetTimer или KeSetTimerEx.

Для драйверов с подпрограммами CustomTimerDpc, использующих периодические таймеры:

Драйвер не может освободить периодический таймер из подпрограммы DPC. Драйверы могут освободить только непериодические таймеры из подпрограммы DPC.

Рассмотрим следующее руководство по проектированию драйверов с подпрограммами CustomDpc и CustomTimerDpc :

Чтобы предотвратить условия гонки, никогда не передавайте один и тот же указатель Dpc в KeSetTimer или KeSetTimerEx и в KeInsertQueueDpc.

Иными словами, предположим, что подпрограмма StartIo драйвера вызывает KeSetTimer или KeSetTimerEx для постановки в очередь подпрограммы CustomTimerDpc, а ISR драйвера вызывает KeInsertQueueDpc одновременно на другом процессоре с одним и тем же указателем Dpc. Эта подпрограмма DPC будет выполняться, когда IRQL на процессоре падает ниже DISPATCH_LEVEL или истекает интервал таймера, в зависимости от того, что происходит в первую очередь. Независимо от того, что произойдет первым, некоторые важные задачи для StartIo или ISR будут просто пропущены подпрограммой DPC.

Кроме того, DPC, используемый двумя стандартными подпрограммами драйверов с очень разными функциями, будет иметь более низкие характеристики производительности, чем отдельные подпрограммы CustomTimerDpc и CustomDpc . DPC должен определить, какие операции выполнять, в зависимости от условий, которые привели к постановке его в очередь через подпрограмму StartIo или ISR. Тестирование этих условий в DPC будет использовать дополнительные циклы ЦП.