Partager via


NdisAllocateSpinLock, fonction (ndis.h)

La fonction NdisAllocateSpinLock initialise une variable de type NDIS_SPIN_LOCK, utilisée pour synchroniser l’accès aux ressources partagées entre les fonctions de pilote non-ISR.

Syntaxe

void NdisAllocateSpinLock(
  [out] PNDIS_SPIN_LOCK SpinLock
);

Paramètres

[out] SpinLock

Pointeur vers une variable opaque qui représente un verrou de rotation.

Valeur de retour

None

Remarques

Avant qu’un pilote appelle NdisAcquireSpinLock, NdisDprAcquireSpinLock ou l’une des fonctions NdisInterlockedXxx , il doit appeler NdisAllocateSpinLock pour initialiser le verrou de rotation passé en tant que paramètre requis à ces fonctions NdisXxx . L’appelant doit fournir un stockage non paginé pour la variable dans SpinLock .

Après avoir appelé NdisAllocateSpinLock, le pilote peut appeler NdisAcquireSpinLock pour obtenir une utilisation exclusive de la ou des ressources que le verrou de rotation protège. Une fois l’accès aux ressources terminé, le pilote appelle NdisReleaseSpinLock afin que d’autres fonctions de pilote puissent accéder aux ressources protégées par ce verrou de rotation.

En règle générale, pour améliorer les performances, un pilote doit utiliser différents verrous pour protéger différentes sections critiques. Ainsi, un pilote peut initialiser plusieurs verrous de rotation avec NdisAllocateSpinLock.

Chaque verrou de rotation alloué par un pilote protège un ensemble discret de ressources partagées contre l’accès simultané par les fonctions de pilote qui s’exécutent à IRQL <= DISPATCH_LEVEL. Par exemple, un pilote qui gère une file d’attente interne de paquets peut initialiser un verrou de rotation pour protéger sa file d’attente et un autre pour protéger un ensemble de variables d’état que plusieurs pilotes fonctionnent, sans inclure miniportInterrupt ou Fonction MiniportDisableInterruptEx , accès pendant que le pilote traite les paquets.

NdisAcquireSpinLock élève l’IRQL à DISPATCH_LEVEL et stocke l’ancien IRQL dans le verrou de rotation. La libération du verrou de rotation définit l’IRQL sur la valeur stockée dans le verrou de rotation. Étant donné que NDIS entre parfois des pilotes à PASSIVE_LEVEL, des problèmes peuvent survenir avec le code suivant :

NdisAcquireSpinLock(A);
NdisAcquireSpinLock(B);
NdisReleaseSpinLock(A);
NdisReleaseSpinLock(B);

Un pilote ne doit pas accéder aux verrous de rotation dans cette séquence pour les raisons suivantes :

  • Entre NdisReleaseSpinLock(A) et NdisReleaseSpinLock(B), le code s’exécute à PASSIVE_LEVEL au lieu de DISPATCH_LEVEL et est sujet à une interruption inappropriée.
  • Après NdisReleaseSpinLock(B), le code s’exécute à DISPATCH_LEVEL ce qui peut provoquer une erreur de l’appelant beaucoup plus tard avec une erreur d’arrêt IRQL_NOT_LESS_OR_EQUAL.
Un pilote ne doit jamais utiliser deux verrous de rotation pour protéger le même (sous-ensemble) de ressources, car les acquisitions de verrous de rotation imbriqués provoquent si fréquemment des interblocages. Même si un pilote peut être conçu pour éviter les interblocages, les acquisitions de verrous de rotation imbriqués ont un effet négatif sur les performances du pilote et le débit d’E/S.

Un pilote miniport ne peut pas utiliser un verrou de rotation pour protéger les ressources que ses fonctions non-ISR partagent avec son MiniportInterrupt ou Fonction MiniportDisableInterruptEx . Pour accéder aux ressources partagées avec une fonction MiniportInterrupt ou MiniportDisableInterruptEx , un pilote miniport doit appeler NdisMSynchronizeWithInterruptEx pour avoir son La fonction MiniportSynchronizeInterrupt accède à ces ressources dans DIRQL.

Lorsqu’un pilote n’a plus besoin d’une protection des ressources, par exemple, lorsqu’une carte réseau est supprimée et que le pilote libère les ressources qu’il a allouées pour cette carte réseau, le pilote appelle NdisFreeSpinLock.

La libération d’un verrou de rotation et la libération d’un verrou de rotation sont potentiellement déroutantes. NdisFreeSpinLock efface la mémoire au niveau de SpinLock afin qu’il ne représente plus un verrou de rotation. La libération d’un verrou de spin acquis avec NdisReleaseSpinLock permet simplement à un autre thread d’exécution d’acquérir ce verrou de rotation.

Pour plus d’informations sur l’acquisition et la publication de verrous de rotation NDIS, consultez Synchronisation et notification dans les pilotes réseau.

Les appelants de NdisAllocateSpinLock peuvent s’exécuter à n’importe quel IRQL. Généralement, un appelant s’exécute à IRQL = PASSIVE_LEVEL pendant l’initialisation.

Configuration requise

Condition requise Valeur
Client minimal pris en charge Pris en charge pour les pilotes NDIS 6.0 et NDIS 5.1 (voir NdisAllocateSpinLock (NDIS 5.1)) dans Windows Vista. Pris en charge pour les pilotes NDIS 5.1 (consultez NdisAllocateSpinLock (NDIS 5.1)) dans Windows XP.
Plateforme cible Universal
En-tête ndis.h (inclure Ndis.h)
Bibliothèque Ndis.lib
IRQL N’importe quel niveau (voir la section Remarques)
Règles de conformité DDI SpinLockDpr(ndis),SpinLockDprRelease(ndis), SpinlockRelease(ndis)

Voir aussi

DriverEntry des pilotes de protocole NDIS

MiniportDisableInterruptEx

MiniportHaltEx

MiniportInitializeEx

MiniportInterrupt

NdisAcquireSpinLock

NdisDprAcquireSpinLock

NdisDprReleaseSpinLock

NdisFreeSpinLock

NdisInterlockedAddUlong

NdisInterlockedInsertHeadList NdisInterlockedInsertTailList NdisInterlockedRemoveHeadList NdisMSynchronizeWithInterruptEx

NdisReleaseSpinLock

NetTimerCallback