NdisAllocateSpinLock 함수(ndis.h)

NdisAllocateSpinLock 함수는 isR이 아닌 드라이버 함수 간에 공유되는 리소스에 대한 액세스를 동기화하는 데 사용되는 NDIS_SPIN_LOCK 형식의 변수를 초기화합니다.

구문

void NdisAllocateSpinLock(
  [out] PNDIS_SPIN_LOCK SpinLock
);

매개 변수

[out] SpinLock

스핀 잠금을 나타내는 불투명 변수에 대한 포인터입니다.

반환 값

없음

설명

드라이버가 NdisAcquireSpinLock, NdisDprAcquireSpinLock 또는 NdisInterlockedXxx 함수를 호출하기 전에 NdisAllocateSpinLock 을 호출하여 이러한 NdisXxx 함수에 필요한 매개 변수로 전달된 스핀 잠금을 초기화해야 합니다. 호출자는 SpinLock 에서 변수에 대해 페이지가 없는 스토리지를 제공해야 합니다.

NdisAllocateSpinLock을 호출한 후 드라이버는 NdisAcquireSpinLock을 호출하여 스핀 잠금이 보호하는 리소스를 독점적으로 사용할 수 있습니다. 리소스 액세스가 완료되면 드라이버는 NdisReleaseSpinLock 을 호출하여 다른 드라이버 함수가 해당 스핀 잠금으로 보호되는 리소스에 액세스할 수 있도록 합니다.

일반적으로 성능을 향상시키려면 드라이버는 다른 잠금을 사용하여 다른 중요한 섹션을 보호해야 합니다. 따라서 드라이버는 NdisAllocateSpinLock을 사용하여 둘 이상의 스핀 잠금을 초기화할 수 있습니다.

드라이버가 할당하는 각 스핀 잠금은 IRQL <= DISPATCH_LEVEL 실행되는 드라이버 함수에 의한 동시 액세스로부터 개별 공유 리소스 집합을 보호합니다. 예를 들어 패킷의 내부 큐를 유지 관리하는 드라이버는 하나의 스핀 잠금을 초기화하여 큐를 보호하고 다른 하나는 MiniportInterrupt 또는 를 포함하지 않고 여러 드라이버가 작동하는 상태 변수 집합을 보호할 수 있습니다. MiniportDisableInterruptEx 함수는 드라이버가 패킷을 처리하는 동안 액세스합니다.

NdisAcquireSpinLock 은 DISPATCH_LEVEL IRQL을 발생시키고 이전 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 중지 오류로 인해 훨씬 나중에 호출자가 오류를 발생시킬 수 있습니다.
중첩된 스핀 잠금 획득으로 인해 교착 상태가 자주 발생하므로 드라이버는 두 개의 스핀 잠금을 사용하여 동일한(하위) 리소스 집합을 보호해서는 안 됩니다. 교착 상태를 방지하기 위해 드라이버를 설계할 수 있더라도 중첩된 스핀 잠금 획득은 드라이버 성능 및 I/O 처리량에 부정적인 영향을 줍니다.

미니포트 드라이버는 스핀 잠금을 사용하여 ISR이 아닌 함수가 MiniportInterrupt 또는 와 공유하는 리소스를 보호할 수 없습니다. MiniportDisableInterruptEx 함수입니다. MiniportInterrupt 또는 MiniportDisableInterruptEx 함수와 공유되는 리소스 액세스하려면 미니포트 드라이버가 를 호출해야 합니다. NdisMSynchronizeWithInterruptEx MiniportSynchronizeInterrupt 함수는 DIRQL에서 해당 리소스에 액세스합니다.

예를 들어 드라이버에 리소스 보호가 더 이상 필요하지 않은 경우(예: NIC가 제거되고 드라이버가 해당 NIC에 할당된 리소스를 해제하는 경우) 드라이버는 NdisFreeSpinLock을 호출합니다.

스핀 잠금을 해제하고 스핀 잠금을 해제하는 것은 잠재적으로 혼란스러울 수 있습니다. NdisFreeSpinLock 은 더 이상 스핀 잠금을 나타내지 않도록 SpinLock 에서 메모리를 지웁니다. 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 참조))에 대해 지원됩니다.
대상 플랫폼 유니버설
헤더 ndis.h(Ndis.h 포함)
라이브러리 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