Utilisation d’une routine CustomTimerDpc

Pour désactiver un objet de minuteur précédemment défini, un pilote appelle KeCancelTimer. Cette routine supprime l’objet minuteur de la file d’attente du minuteur du système. En règle générale, l’objet minuteur n’est pas défini à l’état signalé et la routine CustomTimerDpc n’est pas mise en file d’attente pour l’exécution. Toutefois, si le minuteur est sur le point d’expirer lorsque KeCancelTimer est appelé, l’expiration peut se produire avant que KeCancelTimer ait la possibilité d’accéder à la file d’attente, auquel cas la signalisation et la file d’attente DPC se produisent.

Le rappel de KeSetTimer ou KeSetTimerEx, avec des pointeurs timer et Dpc précédemment spécifiés, avant l’expiration de l’intervalle précédemment spécifié, a les effets suivants :

  • Le noyau supprime l’objet minuteur de la file d’attente du minuteur, sans définir l’état signalé ou mettre en file d’attente la routine CustomTimerDpc .

  • Le noyau réinsétise l’objet minuteur dans la file d’attente du minuteur, à l’aide de la nouvelle valeur DueTime .

L’utilisation du même objet minuteur à des fins différentes peut provoquer des conditions de course ou des erreurs graves de pilote. Par exemple, supposons qu’un pilote spécifie un seul objet minuteur à la fois pour configurer un appel à une routine CustomTimerDpc et pour configurer les attentes dans un thread dédié au pilote. Chaque fois que le thread dédié au pilote appelle KeSetTimer, KeSetTimerEx ou KeCancelTimer pour l’objet de minuteur commun, le thread annule les appels à la routine CustomTimerDpc, si l’objet du minuteur était déjà mis en file d’attente pour un appel CustomTimerDpc.

Si un pilote a des routines CustomTimerDpc et attend également les objets du minuteur dans un contexte de thread nonarbitrary, il doit :

  • N’utilisez jamais un objet de minuteur sensible au contexte de thread dans un contexte de thread non linéaire, ou inversement.

  • Allouez un objet de minuteur distinct pour chaque routine CustomTimerDpc . Chaque ensemble de threads de pilotes ou de routines de pilotes appelés dans un contexte de thread non linéaire doit avoir son propre ensemble d’objets minuteurs « d’attente ».

Si vous utilisez une routine CustomTimerDpc , choisissez soigneusement l’intervalle que le pilote passe dans les appels à KeSetTimer ou KeSetTimerEx. En outre, tenez compte de tous les effets possibles d’un appel à KeCancelTimer avec le même objet de minuteur à partir de n’importe quelle routine de pilote qui effectue cet appel, en particulier sur les plateformes SMP.

Gardez à l’esprit le fait suivant concernant les routines CustomTimerDpc :

Une seule instanciation d’un objet DPC représentant une routine DPC particulière peut être mise en file d’attente pour l’exécution à un moment donné.

Si une deuxième routine de pilote appelle KeSetTimer ou KeSetTimerEx pour exécuter la même routine CustomTimerDpc avant l’expiration de l’intervalle spécifié par le premier appelant, la routine CustomTimerDpc n’est exécutée qu’après l’expiration de l’intervalle spécifié par le deuxième appelant. Dans ces circonstances, le CustomTimerDpc n’effectue aucun des travaux pour lesquels la première routine appelée KeSetTimer ou KeSetTimerEx.

Pour les pilotes qui ont des routines CustomTimerDpc et qui utilisent des minuteurs périodiques :

Un pilote ne peut pas libérer un minuteur périodique d’une routine DPC. Les pilotes peuvent libérer uniquement les minuteurs non ponctuels d’une routine DPC.

Tenez compte des recommandations de conception suivantes pour les pilotes qui ont des routines CustomDpc et CustomTimerDpc :

Pour éviter les conditions de course, ne passez jamais le même pointeur Dpc à KeSetTimerOu KeSetTimerEx et KeInsertQueueDpc.

En d’autres termes, supposons que la routine StartIo d’un pilote appelle KeSetTimer ou KeSetTimerEx pour mettre en file d’attente une routine CustomTimerDpc , et que l’ISR du pilote appelle KeInsertQueueDpc simultanément à partir d’un autre processeur avec le même pointeur Dpc . Cette routine DPC est exécutée lorsque l’IRQL sur un processeur tombe en dessous de DISPATCH_LEVEL ou que l’intervalle du minuteur expire, selon la première éventualité. Quelle que soit la première, un travail essentiel pour StartIo ou ISR serait simplement abandonné par la routine DPC.

En outre, un DPC utilisé par deux routines de pilotes standard avec des fonctionnalités très différentes aurait des caractéristiques de performances plus médiocres que les routines CustomTimerDpc et CustomDpc distinctes. Le DPC doit déterminer les opérations à effectuer, en fonction des conditions qui ont provoqué la mise en file d’attente de la routine StartIo ou de l’ISR. Le test de ces conditions dans la DPC utiliserait des cycles d’UC supplémentaires.