Compartir a través de


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

Ninguno

Observaciones

Antes de que un controlador llame a NdisAcquireSpinLock, NdisDprAcquireSpinLock, o cualquiera de las funciones NdisInterlockedXxx, debe llamar a NdisAllocateSpinLock para inicializar el bloqueo de número pasado como parámetro necesario para estas funciones de NdisXxx. El autor de la llamada 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 giro 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, no incluidas las MiniportInterrupt o función miniportDisableInterruptEx, acceso mientras el controlador procesa paquetes.

NdisAcquireSpinLock eleva IRQL para DISPATCH_LEVEL y almacena el IRQL antiguo en el bloqueo de giro. Al liberar el bloqueo de número, se establece IRQL 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 está ejecutando en DISPATCH_LEVEL lo que podría hacer que el autor de la llamada produzca un error mucho más tarde con un error de detención de IRQL_NOT_LESS_OR_EQUAL.
Un controlador nunca debe usar dos bloqueos de giro 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 miniporte 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 de MiniportInterrupt o MiniportDisableInterruptEx, un controlador de miniport debe llamar a NdisMSynchronizeWithInterruptEx tener su 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 es potencialmente confuso. NdisFreeSpinLock borra la memoria en SpinLock para que ya no represente un bloqueo de giro. Liberar un bloqueo de giro adquirido con NdisReleaseSpinLock simplemente permite que otro subproceso de ejecución adquiera ese bloqueo de giro.

Para obtener más información sobre cómo adquirir y liberar bloqueos de giro de 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 Valor
cliente mínimo admitido Compatible con los controladores NDIS 6.0 y NDIS 5.1 (consulte NdisAllocateSpinLock (NDIS 5.1)) en Windows Vista. Compatible con los controladores NDIS 5.1 (consulte NdisAllocateSpinLock (NDIS 5.1)) en Windows XP.
de la plataforma de destino de Universal
encabezado de ndis.h (incluya Ndis.h)
biblioteca de 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 of NDIS Protocol Drivers

MiniportDisableInterruptEx

MiniportHaltEx

MiniportInitializeEx

MiniportInterrupt

NdisAcquireSpinLock

NdisDprAcquireSpinLock

NdisDprReleaseSpinLock

NdisFreeSpinLock

NdisInterlockedAddUlong

NdisInterlockedInsertHeadList NdisInterlockedInsertTailList NdisInterlockedRemoveHeadList NdisMSynchronizeWithInterruptEx

NdisReleaseSpinLock

NetTimerCallback