Partager via


Accès aux informations d’état partagé

Utilisez les instructions générales suivantes pour la conception et l’écriture de routines SynchCritSection qui conservent l’état :

  • Pour accéder aux données auxquelles un ISR accède également, une routine de pilote doit appeler une routine SynchCritSection . Le code de section non critique peut être interrompu. N’oubliez pas qu’il ne suffit pas d’acquérir simplement un verrou de rotation pour protéger les données auxquelles les ISR accèdent également, car les ISR s’exécutent au niveau du DIRQL et l’acquisition d’un verrou de rotation (KeAcquireSpinLock) ne fait que lever IRQL à DISPATCH_LEVEL, ce qui permet une interruption pour appeler l’ISR sur le processeur actuel.

  • Donnez à chaque routine SynchCritSection qui conserve la responsabilité des informations d’état pour un ensemble discret de variables d’état. Autrement dit, évitez d’écrire des routines SynchCritSection qui conservent les informations d’état qui se chevauchent.

    Cela empêche la contention, et éventuellement les conditions de concurrence, entre les routines SynchCritSection (et l’ISR) qui tentent d’accéder simultanément au même état.

    Cela garantit également que chaque routine SynchCritSection retourne le contrôle aussi rapidement que possible, car une routine SynchCritSection n’a jamais besoin d’attendre qu’une autre qui met à jour certaines des mêmes informations d’état pour retourner le contrôle.

  • Évitez d’écrire une routine SynchCritSection unique et volumineuse à usage général qui effectue plus de tests de conditions pour déterminer ce qu’il faut faire que d’effectuer un travail utile. D’autre part, évitez d’avoir de nombreuses routines SynchCritSection qui n’exécutent jamais d’instruction conditionnelle, car chacune met à jour un seul octet d’informations d’état.

  • Chaque routine SynchCritSection doit retourner le contrôle aussi rapidement que possible, car l’exécution d’une routine SynchCritSection empêche l’exécution de l’ISR du pilote.

Voici une technique de maintenance d’un compteur de minuteur dans une extension d’appareil. Supposons que le pilote utilise le compteur pour déterminer si une opération d’E/S a expiré. Supposons également que le pilote ne chevauche pas les opérations d’E/S.

  • La routine StartIo du pilote initialise le compteur du minuteur à une valeur initiale pour chaque demande d’E/S. Le pilote ajoute ensuite une seconde à sa valeur de délai d’attente de l’appareil, au cas où sa routine IoTimer vient de retourner le contrôle.

  • L’ISR du pilote doit définir ce compteur du minuteur sur moins un.

  • La routine IoTimer du pilote est appelée une fois par seconde pour lire le compteur de temps et déterminer si l’ISR l’a déjà défini sur moins un. Si ce n’est pas le cas, la routine IoTimer décrémente le compteur à l’aide de KeSynchronizeExecution pour appeler une SynchCritSection_1 routine.

    Si le compteur passe à zéro, indiquant que la requête a expiré, la routine SynchCritSection_1 appelle une routine SynchCritSection_2 pour programmer une opération de réinitialisation de l’appareil. Si le compteur est moins un, la routine IoTimer retourne simplement.

  • Si la routine DpcForIsr du pilote doit reprogrammer l’appareil pour commencer une opération de transfert partiel, elle doit réinitialiser le compteur du minuteur comme l’a fait la routine StartIo .

    La routine DpcForIsr doit également utiliser KeSynchronizeExecution pour appeler la routine SynchCritSection_2, ou éventuellement une routine SynchCritSection_3, pour programmer l’appareil pour une autre opération de transfert.

Dans ce scénario, le pilote a plusieurs routines SynchCritSection , chacune avec des responsabilités distinctes et spécifiques ; un pour maintenir son compteur minuteur et un ou plusieurs autres pour programmer l’appareil. Chaque routine SynchCritSection peut retourner rapidement le contrôle, car elle effectue une tâche unique et discrète.

Notez que le pilote a une seule routine SynchCritSection_1 qui, avec l’ISR du pilote, maintient l’état du compteur du minuteur. Par conséquent, il n’y a pas de conflit pour l’accès au compteur du minuteur entre plusieurs routines SynchCritSection et l’ISR.