NdisAllocateSpinLock 関数 (ndis.h)

NdisAllocateSpinLock 関数は、ISR 以外のドライバー関数間で共有されるリソースへのアクセスを同期するために使用される、NDIS_SPIN_LOCK型の変数を初期化します。

構文

void NdisAllocateSpinLock(
  [out] PNDIS_SPIN_LOCK SpinLock
);

パラメーター

[out] SpinLock

スピン ロックを表す不透明な変数へのポインター。

戻り値

なし

解説

ドライバーは、 NdisAcquireSpinLockNdisDprAcquireSpinLock、または NdisInterlockedXxx 関数のいずれかを呼び出す前に、 NdisAllocateSpinLock を呼び出して、これらの NdisXxx 関数に必要なパラメーターとして渡されるスピン ロックを初期化する必要があります。 呼び出し元は 、SpinLock で変数の非ページ ストレージを提供する必要があります。

NdisAllocateSpinLock を呼び出した後、ドライバーは NdisAcquireSpinLock を呼び出して、スピン ロックによって保護されるリソースの排他的な使用を取得できます。 リソース アクセスが完了すると、ドライバーは NdisReleaseSpinLock を 呼び出して、他のドライバー関数がそのスピン ロックによって保護されたリソースにアクセスできるようにします。

一般的なルールとして、パフォーマンスを向上させるには、ドライバーが異なるロックを使用して、さまざまな重要なセクションを保護する必要があります。 したがって、ドライバーは NdisAllocateSpinLock を使用して複数のスピン ロックを初期化する可能性があります。

ドライバーが割り当てる各スピン ロックは、IRQL <= DISPATCH_LEVELで実行されるドライバー関数による同時アクセスから共有リソースの個別のセットを保護します。 たとえば、パケットの内部キューを維持するドライバーは、1 つのスピン ロックを初期化してキューを保護し、もう 1 つは 、MiniportInterrupt や を含まない、複数のドライバーが機能する一連の状態変数を保護する場合があります。 MiniportDisableInterruptEx 関数。ドライバーがパケットの処理中にアクセスします。

NdisAcquireSpinLock は IRQL をDISPATCH_LEVELに上げ、古い IRQL をスピン ロックに格納します。 スピン ロックを解放すると、IRQL はスピン ロックに格納されている値に設定されます。 NDIS はPASSIVE_LEVELでドライバーに入る場合があるため、次のコードで問題が発生する可能性があります。

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

ドライバーは、次の理由により、このシーケンスのスピン ロックにアクセスしないでください。

  • NdisReleaseSpinLock(A) と NdisReleaseSpinLock(B) の間で、コードはDISPATCH_LEVELではなくPASSIVE_LEVELで実行されており、不適切な中断の対象となります。
  • NdisReleaseSpinLock(B) の後、コードは DISPATCH_LEVEL で実行されているため、呼び出し元が後でエラーを発生させ、IRQL_NOT_LESS_OR_EQUAL停止エラーが発生する可能性があります。
入れ子になったスピン ロックの取得によってデッドロックが頻繁に発生するため、ドライバーで同じ (サブ) セットのリソースを保護するために、2 つのスピン ロックを使用しないでください。 デッドロックを防ぐためにドライバーを設計できたとしても、入れ子になったスピン ロックの取得は、ドライバーのパフォーマンスと I/O スループットに悪影響を及ぼします。

ミニポート ドライバーは、スピン ロックを使用して、ISR 以外の関数がその MiniportInterrupt または と共有するリソースを保護することはできません MiniportDisableInterruptEx 関数。 MiniportInterrupt または MiniportDisableInterruptEx 関数と共有されているリソースにアクセスするには、ミニポート ドライバーが を呼び出す必要があります NdisMSynchronizeWithInterruptEx MiniportSynchronizeInterrupt 関数は、DIRQL でこれらのリソースにアクセスします。

たとえば、NIC が削除され、ドライバーがその NIC に割り当てられたリソースを解放する場合など、ドライバーがリソース保護を必要としなくなった場合、ドライバーは NdisFreeSpinLock を呼び出します。

スピン ロックを解放し、スピン ロックを解放すると、混乱を招く可能性があります。 NdisFreeSpinLockスピン ロック のメモリをクリアして、スピン ロックを表さなくなりました。 NdisReleaseSpinLock を使用して取得したスピン ロックを解放すると、別の実行スレッドがそのスピン ロックを取得できます。

NDIS スピン ロックの取得と解放の詳細については、「 ネットワーク ドライバーでの同期と通知」を参照してください。

NdisAllocateSpinLock の呼び出し元は、任意の IRQL で実行できます。 通常、呼び出し元は初期化中に IRQL = PASSIVE_LEVELで実行されます。

要件

要件
サポートされている最小のクライアント Windows Vista の NDIS 6.0 および NDIS 5.1 ドライバー (「NdisAllocateSpinLock (NDIS 5.1)」を参照) でサポートされています。 Windows XP の NDIS 5.1 ドライバー (「NdisAllocateSpinLock (NDIS 5.1)」を参照) でサポートされています。
対象プラットフォーム ユニバーサル
Header ndis.h (Ndis.h を含む)
Library Ndis.lib
IRQL 任意のレベル (「解説」セクションを参照)
DDI コンプライアンス規則 SpinLockDpr(ndis)SpinLockDprRelease(ndis)SpinlockRelease(ndis)

こちらもご覧ください

NDIS プロトコル ドライバーの DriverEntry

MiniportDisableInterruptEx

MiniportHaltEx

MiniportInitializeEx

MiniportInterrupt

NdisAcquireSpinLock

NdisDprAcquireSpinLock

NdisDprReleaseSpinLock

NdisFreeSpinLock

NdisInterlockedAddUlong

NdisInterlockedInsertHeadList NdisInterlockedInsertTailList NdisInterlockedRemoveHeadList NdisMSynchronizeWithInterruptEx

NdisReleaseSpinLock

NetTimerCallback