NdisAllocateSpinLock-Funktion (ndis.h)

Die NdisAllocateSpinLock-Funktion initialisiert eine Variable vom Typ NDIS_SPIN_LOCK, die zum Synchronisieren des Zugriffs auf Ressourcen verwendet wird, die von Nicht-ISR-Treiberfunktionen freigegeben werden.

Syntax

void NdisAllocateSpinLock(
  [out] PNDIS_SPIN_LOCK SpinLock
);

Parameter

[out] SpinLock

Zeiger auf eine undurchsichtige Variable, die eine Drehsperre darstellt.

Rückgabewert

Keine

Bemerkungen

Bevor ein Treiber NdisAcquireSpinLock, NdisDprAcquireSpinLock oder eine der NdisInterlockedXxx-Funktionen aufruft, muss er NdisAllocateSpinLock aufrufen, um die Drehsperre zu initialisieren, die als erforderlicher Parameter für diese NdisXxx-Funktionen übergeben wurde. Der Aufrufer muss nicht ausgelagerten Speicher für die Variable in SpinLock bereitstellen.

Nach dem Aufruf von NdisAllocateSpinLock kann der Treiber NdisAcquireSpinLock aufrufen, um die exklusive Nutzung der Ressourcen zu erhalten, die die Spinsperre schützt. Wenn der Ressourcenzugriff abgeschlossen ist, ruft der Treiber NdisReleaseSpinLock auf, damit andere Treiberfunktionen auf die durch diese Spinsperre geschützten Ressourcen zugreifen können.

Im Allgemeinen sollte ein Treiber zur Verbesserung der Leistung verschiedene Sperren verwenden, um verschiedene kritische Abschnitte zu schützen. Daher kann ein Treiber mehr als eine Drehsperre mit NdisAllocateSpinLock initialisieren.

Jede Drehsperre, die ein Treiber ordnet, schützt einen diskreten Satz freigegebener Ressourcen vor dem gleichzeitigen Zugriff durch Treiberfunktionen, die mit IRQL <= DISPATCH_LEVEL ausgeführt werden. Beispielsweise kann ein Treiber, der eine interne Paketwarteschlange verwaltet, eine Spinsperre zum Schutz seiner Warteschlange initialisieren, und eine andere, um eine Reihe von Zustandsvariablen zu schützen, die mehrere Treiberfunktionen, einschließlich der MiniportInterrupt oder MiniportDisableInterruptEx-Funktion , Zugriff, während der Treiber Pakete verarbeitet.

NdisAcquireSpinLock erhöht die IRQL auf DISPATCH_LEVEL und speichert die alte IRQL in der Spin-Sperre. Durch Das Loslassen der Drehsperre wird der IRQL auf den wert festgelegt, der in der Spinsperre gespeichert ist. Da NDIS manchmal Treiber an PASSIVE_LEVEL eingibt, können Probleme mit dem folgenden Code auftreten:

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

Ein Treiber sollte aus den folgenden Gründen nicht auf Drehsperren in dieser Sequenz zugreifen:

  • Zwischen NdisReleaseSpinLock(A) und NdisReleaseSpinLock(B) wird der Code auf PASSIVE_LEVEL anstelle von DISPATCH_LEVEL ausgeführt und unterliegt einer unangemessenen Unterbrechung.
  • Nach NdisReleaseSpinLock(B) wird der Code auf DISPATCH_LEVEL ausgeführt, was dazu führen kann, dass der Aufrufer viel später einen Fehler mit einem IRQL_NOT_LESS_OR_EQUAL Stoppfehler verursacht.
Ein Treiber sollte nie zwei Spinsperren verwenden, um denselben (Unter-)Ressourcensatz zu schützen, da geschachtelte Spin-Lock-Käufe so häufig Deadlocks verursachen. Auch wenn ein Treiber so konzipiert werden könnte, dass er Deadlocks verhindert, wirken sich geschachtelte Spin lock-Käufe negativ auf die Treiberleistung und den E/A-Durchsatz aus.

Ein Miniporttreiber kann keine Spinsperre verwenden, um Ressourcen zu schützen, die seine Nicht-ISR-Funktionen mit seinem MiniportInterrupt oder teilen. MiniportDisableInterruptEx-Funktion . Um auf Ressourcen zuzugreifen, die mit einer Funktion "MiniportInterrupt " oder "MiniportDisableInterruptEx " freigegeben wurden, muss ein Miniporttreiber aufrufen. NdisMSynchronizeWithInterruptEx , um seine Die MiniportSynchronizeInterrupt-Funktion greift auf diese Ressourcen unter DIRQL zu.

Wenn ein Treiber keinen Ressourcenschutz mehr benötigt, z. B. wenn eine NIC entfernt wird und der Treiber die Ressourcen freigibt, die er für diese NIC zugewiesen hat, ruft der Treiber NdisFreeSpinLock auf.

Das Freigeben einer Spinsperre und das Freigeben einer Drehsperre sind möglicherweise verwirrend. NdisFreeSpinLock löscht den Arbeitsspeicher bei SpinLock , sodass er keine Spinlock-Sperre mehr darstellt. Durch das Freigeben einer erworbenen Spinsperre mit NdisReleaseSpinLock kann einfach ein anderer Ausführungsthread diese Spinsperre abrufen.

Weitere Informationen zum Abrufen und Freigeben von NDIS-Spinsperren finden Sie unter Synchronisierung und Benachrichtigung in Netzwerktreibern.

Aufrufer von NdisAllocateSpinLock können auf jedem IRQL ausgeführt werden. Normalerweise wird ein Aufrufer bei IRQL = PASSIVE_LEVEL während der Initialisierung ausgeführt.

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Unterstützt für NDIS 6.0- und NDIS 5.1-Treiber (siehe NdisAllocateSpinLock (NDIS 5.1)) in Windows Vista. Unterstützt für NDIS 5.1-Treiber (siehe NdisAllocateSpinLock (NDIS 5.1)) in Windows XP.
Zielplattform Universell
Header ndis.h (einschließlich Ndis.h)
Bibliothek Ndis.lib
IRQL Beliebige Ebene (siehe Abschnitt Hinweise)
DDI-Complianceregeln SpinLockDpr(ndis), SpinLockDprRelease(ndis), SpinlockRelease(ndis)

Weitere Informationen

DriverEntry von NDIS-Protokolltreibern

MiniportDisableInterruptEx

MiniportHaltEx

MiniportInitializeEx

MiniportInterrupt

NdisAcquireSpinLock

NdisDprAcquireSpinLock

NdisDprReleaseSpinLock

NdisFreeSpinLock

NdisInterlockedAddUlong

NdisInterlockedInsertHeadList NdisInterlockedInsertTailList NdisInterlockedRemoveHeadList NdisMSynchronizeWithInterruptEx

NdisReleaseSpinLock

NetTimerCallback