Usando uma rotina CustomTimerDpc
Para desabilitar um objeto de temporizador definido anteriormente, um driver chama KeCancelTimer. Essa rotina remove o objeto timer da fila do temporizador do sistema. Em geral, o objeto timer não é definido como o estado sinalizado e a rotina CustomTimerDpc não está na fila para execução. No entanto, se o temporizador estiver prestes a expirar quando KeCancelTimer for chamado, a expiração poderá ocorrer antes que KeCancelTimer tenha a chance de acessar a fila de tempo, caso em que a sinalização e a fila DPC ocorrerão.
O recall de KeSetTimer ou KeSetTimerEx, com ponteiros De temporizador e Dpc especificados anteriormente, antes do intervalo especificado anteriormente expirar, tem os seguintes efeitos:
O kernel remove o objeto timer da fila do temporizador, sem definir o objeto para o estado sinalizado ou enfileirar a rotina CustomTimerDpc .
O kernel reinsere o objeto timer na fila do temporizador, usando o novo valor DueTime .
Usar o mesmo objeto de temporizador para fins diferentes pode causar condições de corrida ou erros graves do piloto. Por exemplo, suponha que um driver especifique um único objeto de temporizador para configurar uma chamada para uma rotina CustomTimerDpc e configurar esperas em um thread dedicado ao driver. Sempre que o thread dedicado ao driver chama KeSetTimer, KeSetTimerEx ou KeCancelTimer para o objeto de temporizador comum, o thread cancelava chamadas para a rotina CustomTimerDpc , se o objeto timer já estivesse na fila para uma chamada CustomTimerDpc .
Se um driver tiver rotinas CustomTimerDpc e também aguardar objetos de temporizador em um contexto de thread nonarbitrary, ele deverá:
Nunca use um objeto timer sensível ao contexto de thread em um contexto de thread nonarbitrary ou vice-versa.
Aloque um objeto timer separado para cada rotina CustomTimerDpc . Cada conjunto de threads de driver ou rotinas de driver que são chamados em um contexto de thread nonarbitrary deve ter seu próprio conjunto de objetos de temporizador "esperados".
Se você usar uma rotina CustomTimerDpc , escolha cuidadosamente o intervalo que o driver passa em chamadas para KeSetTimer ou KeSetTimerEx. Além disso, considere todos os possíveis efeitos de uma chamada para KeCancelTimer com o mesmo objeto de temporizador de qualquer rotina de driver que faça essa chamada, especialmente em plataformas SMP.
Tenha em mente o seguinte fato sobre rotinas CustomTimerDpc :
Apenas uma instanciação de um objeto DPC que representa uma rotina de DPC específica pode ser enfileirada para execução a qualquer momento.
Se uma segunda rotina de driver chamar KeSetTimer ou KeSetTimerEx para executar a mesma rotina CustomTimerDpc antes que o intervalo especificado pelo primeiro chamador expire, a rotina CustomTimerDpc será executada somente após o intervalo especificado pelo segundo chamador expirar. Nessas circunstâncias, o CustomTimerDpc não faz nenhum trabalho para o qual a primeira rotina chamada KeSetTimer ou KeSetTimerEx.
Para drivers que têm rotinas CustomTimerDpc e usam temporizadores periódicos:
Um driver não pode desalocar um temporizador periódico de uma rotina de DPC. Os drivers podem desalocar apenas temporizadores não periódicos de uma rotina DPC.
Considere a seguinte diretriz de design para drivers que têm rotinas CustomDpc e CustomTimerDpc :
Para evitar condições de corrida, nunca passe o mesmo ponteiro Dpc para KeSetTimer ou KeSetTimerEx e KeInsertQueueDpc.
Em outras palavras, suponha que a rotina StartIo de um driver chame KeSetTimer ou KeSetTimerEx para enfileirar uma rotina CustomTimerDpc e o ISR do driver chame KeInsertQueueDpc simultaneamente de outro processador com o mesmo ponteiro Dpc . Essa rotina de DPC será executada quando IRQL em um processador ficar abaixo DISPATCH_LEVEL ou o intervalo de temporizador expirar, o que vier primeiro. O que vier primeiro, algum trabalho essencial para o StartIo ou ISR seria simplesmente descartado pela rotina DPC.
Além disso, um DPC usado por duas rotinas de driver padrão com funcionalidades muito diferentes teria características de desempenho inferiores às rotinas customTimerDpc e CustomDpc separadas. O DPC teria que determinar quais operações realizar, dependendo das condições que causaram a rotina StartIo ou o ISR a enfileirar. O teste para essas condições no DPC usaria ciclos de CPU adicionais.