Présentation des verrous de rotation
Les verrous de rotation sont des mécanismes de synchronisation définis par le noyau, en mode noyau uniquement, exportés sous la forme d’un type opaque : KSPIN_LOCK. Un verrou de rotation peut être utilisé pour protéger les données partagées ou les ressources contre l’accès simultané. Lors de l’exécution à IRQL <= DISPATCH_LEVEL, un pilote peut utiliser KeAcquireInStackQueuedSpinLock et KeReleaseInStackQueuedSpinLock pour acquérir et libérer le verrou de rotation en tant que verrou de rotation mis en file d’attente.
Les appelants s’exécutant à IRQL >= DISPATCH_LEVEL peuvent également appeler KeAcquireSpinLockAtDpcLevel et KeReleaseSpinLockFromDpcLevel pour améliorer les performances du pilote.
De nombreux composants utilisent des verrous de rotation, y compris des pilotes. Tout type de pilote peut utiliser un ou plusieurs verrous de rotation exécutifs. Par exemple, la plupart des systèmes de fichiers utilisent une file d’attente de travail interblocée dans l’extension de périphérique du pilote de système de fichiers (FSD) pour stocker les adresses IP IRP traitées à la fois par les routines de rappel de thread de travail du système de fichiers et par le FSD. Une file d’attente de travail interblocée est protégée par un verrou de spin exécutif, qui résout la contention entre le FSD qui tente d’insérer des IRPs dans la file d’attente et tous les threads tentent simultanément de supprimer les IRPs. Comme autre exemple, le pilote du contrôleur de floppy système utilise deux verrous de rotation exécutifs. Un verrou de rotation exécutif protège une file d’attente de travail interblocée partagée avec le thread dédié à l’appareil de ce pilote ; l’autre protège un objet minuteur partagé par trois routines de pilote.
Les verrous de rotation mis en file d’attente offrent de meilleures performances que les verrous de rotation ordinaires pour les verrous de contention élevés sur les machines multiprocesseurs. Pour plus d’informations, consultez Verrous de rotation mis en file d’attente. Les pilotes peuvent également utiliser KeAcquireSpinLock et KeReleaseSpinLock pour acquérir et libérer un verrou de rotation en tant que verrou de rotation ordinaire.
Pour synchroniser l’accès à des structures de données simples, les pilotes peuvent utiliser l’une des routines ExInterlockedXxx pour garantir l’accès atomique à la structure de données. Les pilotes qui utilisent ces routines n’ont pas besoin d’acquérir ou de libérer explicitement le verrou de rotation.
Chaque pilote disposant d’un ISR utilise un verrou de rotation d’interruption pour protéger toutes les données ou matériels partagés entre son ISR et ses routines SynchCritSection qui sont généralement appelées à partir de ses routines StartIo et DpcForIsr. Un verrou de rotation d’interruption est associé à l’ensemble d’objets d’interruption créés lorsque le pilote appelle Io Connecter Interrupt, comme décrit dans l’inscription d’un ISR.
Suivez ces instructions pour utiliser des verrous de rotation dans les pilotes :
Fournissez le stockage de toutes les données ou ressources protégées par un verrou de rotation et pour le verrou de rotation correspondant dans la mémoire de l’espace système résident (pool non paginé, comme indiqué dans la figure espaces de mémoire virtuelle et mémoire physique). Un pilote doit fournir le stockage pour tous les verrous de rotation exécutifs qu’il utilise. Toutefois, un pilote de périphérique n’a pas besoin de fournir le stockage d’un verrou de rotation d’interruption, sauf s’il a un ISR multivectoriel ou plusieurs ISR, comme décrit dans l’inscription d’un ISR.
Appelez KeInitializeSpinLock pour initialiser chaque verrou de rotation pour lequel le pilote fournit un stockage avant de l’utiliser pour synchroniser l’accès aux données partagées ou à la ressource qu’il protège.
Appelez toutes les routines de support qui utilisent un verrou de rotation à un IRQL approprié, généralement à <= DISPATCH_LEVEL pour les verrous de rotation exécutifs ou à <= DIRQL pour un verrou de rotation d’interruption associé aux objets d’interruption du pilote.
Implémentez des routines pour s’exécuter le plus rapidement possible pendant qu’elles contiennent un verrou de rotation. Aucune routine ne doit contenir de verrou de rotation pendant plus de 25 microsecondes.
N’implémentez jamais les routines qui effectuent l’une des opérations suivantes lors de la conservation d’un verrou de rotation :
Provoquez des exceptions matérielles ou déclenchez des exceptions logicielles.
Essayez d’accéder à la mémoire paginable.
Effectuez un appel récursif qui provoquerait un interblocage ou pourrait entraîner la tenue d’un verrou de rotation pendant plus de 25 microsecondes.
Tenter d’acquérir un autre verrou de rotation si cela peut entraîner un interblocage.
Appelez une routine externe qui enfreint l’une des règles précédentes.