Función NdisAllocateSpinLock (ndis.h)

La función NdisAllocateSpinLock inicializa una variable de tipo NDIS_SPIN_LOCK, que se usa para sincronizar el acceso a los recursos compartidos entre funciones de controlador que no son ISR.

Sintaxis

void NdisAllocateSpinLock(
  [out] PNDIS_SPIN_LOCK SpinLock
);

Parámetros

[out] SpinLock

Puntero a una variable opaca que representa un bloqueo de número.

Valor devuelto

None

Observaciones

Antes de que un controlador llame a NdisAcquireSpinLock, NdisDprAcquireSpinLock o a cualquiera de las funciones NdisInterlockedXxx , debe llamar a NdisAllocateSpinLock para inicializar el bloqueo de número pasado como parámetro necesario para estas funciones NdisXxx . El llamador debe proporcionar almacenamiento no paginado para la variable en SpinLock .

Después de llamar a NdisAllocateSpinLock, el controlador puede llamar a NdisAcquireSpinLock para obtener el uso exclusivo de los recursos que protege el bloqueo de número. Cuando se completa el acceso a los recursos, el controlador llama a NdisReleaseSpinLock para que otras funciones del controlador puedan acceder a los recursos protegidos por ese bloqueo de número.

Como regla general, para mejorar el rendimiento, un controlador debe usar bloqueos diferentes para proteger diferentes secciones críticas. Por lo tanto, un controlador puede inicializar más de un bloqueo de número con NdisAllocateSpinLock.

Cada bloqueo de número que asigna un controlador protege un conjunto discreto de recursos compartidos del acceso simultáneo por las funciones de controlador que se ejecutan en IRQL <= DISPATCH_LEVEL. Por ejemplo, un controlador que mantiene una cola interna de paquetes podría inicializar un bloqueo de número para proteger su cola y otro para proteger un conjunto de variables de estado que varias funciones de controlador, sin incluir miniportInterrupt o Función MiniportDisableInterruptEx , acceso mientras el controlador está procesando paquetes.

NdisAcquireSpinLock eleva irQL para DISPATCH_LEVEL y almacena el IRQL antiguo en el bloqueo de giro. Al liberar el bloqueo de número, el IRQL se establece en el valor almacenado en el bloqueo de número. Dado que NDIS a veces entra en controladores en PASSIVE_LEVEL, pueden surgir problemas con el código siguiente:

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

Un controlador no debe acceder a los bloqueos de número en esta secuencia por los siguientes motivos:

  • Entre NdisReleaseSpinLock(A) y NdisReleaseSpinLock(B), el código se ejecuta en PASSIVE_LEVEL en lugar de DISPATCH_LEVEL y está sujeto a interrupciones inapropiadas.
  • Después de NdisReleaseSpinLock(B), el código se ejecuta en DISPATCH_LEVEL, lo que podría hacer que el autor de la llamada genere un error mucho más tarde con un error de IRQL_NOT_LESS_OR_EQUAL detención.
Un controlador nunca debe usar dos bloqueos de número para proteger el mismo conjunto (sub)conjunto de recursos porque las adquisiciones de bloqueos de giro anidados suelen provocar interbloqueos. Incluso si un controlador podría diseñarse para evitar interbloqueos, las adquisiciones de bloqueos de giro anidados tienen un efecto adverso en el rendimiento del controlador y el rendimiento de E/S.

Un controlador de minipuerto no puede usar un bloqueo de número para proteger los recursos que comparten sus funciones que no son ISR con su MiniportInterrupt o Función MiniportDisableInterruptEx . Para acceder a los recursos compartidos con una función MiniportInterrupt o MiniportDisableInterruptEx , un controlador de minipuerto debe llamar a NdisMSynchronizeWithInterruptEx para tener su La función MiniportSynchronizeInterrupt accede a esos recursos en DIRQL.

Cuando un controlador ya no requiere protección de recursos, por ejemplo, cuando se quita una NIC y el controlador libera los recursos asignados para esa NIC, el controlador llama a NdisFreeSpinLock.

Liberar un bloqueo de giro y liberar un bloqueo de giro son potencialmente confusos. NdisFreeSpinLock borra la memoria en SpinLock para que ya no represente un bloqueo de número. Liberar un bloqueo de giro adquirido con NdisReleaseSpinLock simplemente permite que otro subproceso de ejecución adquiera ese bloqueo de número.

Para obtener más información sobre cómo adquirir y liberar bloqueos de número NDIS, consulte Sincronización y notificación en controladores de red.

Los autores de llamadas de NdisAllocateSpinLock se pueden ejecutar en cualquier IRQL. Normalmente, un autor de llamada se ejecuta en IRQL = PASSIVE_LEVEL durante la inicialización.

Requisitos

Requisito Value
Cliente mínimo compatible Compatible con los controladores NDIS 6.0 y NDIS 5.1 (consulta NdisAllocateSpinLock (NDIS 5.1)) en Windows Vista. Compatible con los controladores NDIS 5.1 (consulta NdisAllocateSpinLock (NDIS 5.1)) en Windows XP.
Plataforma de destino Universal
Encabezado ndis.h (incluya Ndis.h)
Library Ndis.lib
IRQL Cualquier nivel (consulte la sección Comentarios)
Reglas de cumplimiento de DDI SpinLockDpr(ndis), SpinLockDprRelease(ndis), SpinlockRelease(ndis)

Consulte también

DriverEntry de controladores de protocolo NDIS

MiniportDisableInterruptEx

MiniportHaltEx

MiniportInitializeEx

MiniportInterrupt

NdisAcquireSpinLock

NdisDprAcquireSpinLock

NdisDprReleaseSpinLock

NdisFreeSpinLock

NdisInterlockedAddUlong

NdisInterlockedInsertHeadList NdisInterlockedInsertTailList NdisInterlockedRemoveHeadList NdisMSynchronizeWithInterruptEx

NdisReleaseSpinLock

NetTimerCallback