Compartilhar via


Função NdisAllocateSpinLock (ndis.h)

A função NdisAllocateSpinLock inicializa uma variável do tipo NDIS_SPIN_LOCK, usada para sincronizar o acesso a recursos compartilhados entre funções de driver não ISR.

Sintaxe

void NdisAllocateSpinLock(
  [out] PNDIS_SPIN_LOCK SpinLock
);

Parâmetros

[out] SpinLock

Ponteiro para uma variável opaca que representa um bloqueio de rotação.

Retornar valor

Nenhum

Comentários

Antes que um driver chame NdisAcquireSpinLock, NdisDprAcquireSpinLock ou qualquer uma das funções NdisInterlockedXxx , ele deve chamar NdisAllocateSpinLock para inicializar o bloqueio de rotação passado como um parâmetro necessário para essas funções NdisXxx . O chamador deve fornecer armazenamento nãopagado para a variável em SpinLock .

Depois de chamar NdisAllocateSpinLock, o driver pode chamar NdisAcquireSpinLock para obter o uso exclusivo dos recursos protegidos pelo bloqueio de rotação. Quando o acesso a recursos for concluído, o driver chamará NdisReleaseSpinLock para que outras funções de driver possam acessar os recursos protegidos por esse bloqueio de rotação.

Como regra geral, para melhorar o desempenho, um driver deve usar bloqueios diferentes para proteger diferentes seções críticas. Portanto, um driver pode inicializar mais de um bloqueio de rotação com NdisAllocateSpinLock.

Cada bloqueio de rotação alocado por um driver protege um conjunto discreto de recursos compartilhados contra o acesso simultâneo por funções de driver executadas em IRQL <= DISPATCH_LEVEL. Por exemplo, um driver que mantém uma fila interna de pacotes pode inicializar um bloqueio de rotação para proteger sua fila e outro para proteger um conjunto de variáveis de estado que várias funções de driver, não incluindo o MiniportInterrupt ou Função MiniportDisableInterruptEx , acesse enquanto o driver está processando pacotes.

NdisAcquireSpinLock eleva o IRQL para DISPATCH_LEVEL e armazena o IRQL antigo no bloqueio de rotação. A liberação do bloqueio de rotação define o IRQL como o valor armazenado no bloqueio de rotação. Como o NDIS às vezes insere drivers em PASSIVE_LEVEL, podem surgir problemas com o seguinte código:

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

Um driver não deve acessar bloqueios de rotação nesta sequência pelos seguintes motivos:

  • Entre NdisReleaseSpinLock(A) e NdisReleaseSpinLock(B), o código está sendo executado em PASSIVE_LEVEL em vez de DISPATCH_LEVEL e está sujeito a interrupções inadequadas.
  • Depois de NdisReleaseSpinLock(B), o código está em execução no DISPATCH_LEVEL o que pode fazer com que o chamador falha muito mais tarde com um erro de parada IRQL_NOT_LESS_OR_EQUAL.
Um driver nunca deve usar dois bloqueios de rotação para proteger o mesmo (sub)conjunto de recursos porque aquisições de bloqueio de rotação aninhadas causam deadlocks com tanta frequência. Mesmo que um driver possa ser projetado para evitar deadlocks, aquisições aninhadas de bloqueio de rotação têm um efeito adverso no desempenho do driver e na taxa de transferência de E/S.

Um driver de miniporta não pode usar um bloqueio de rotação para proteger os recursos que suas funções não ISR compartilham com seu MiniportInterrupt ou Função MiniportDisableInterruptEx . Para acessar recursos compartilhados com uma função MiniportInterrupt ou MiniportDisableInterruptEx , um driver de miniporte deve chamar NdisMSynchronizeWithInterruptEx para ter seu A função MiniportSynchronizeInterrupt acessa esses recursos em DIRQL.

Quando um driver não requer mais proteção de recursos, por exemplo, quando uma NIC está sendo removida e o driver está liberando os recursos alocados para essa NIC, o driver chama NdisFreeSpinLock.

Liberar um bloqueio de rotação e liberar um bloqueio de rotação é potencialmente confuso. NdisFreeSpinLock limpa a memória no SpinLock para que ele não represente mais um bloqueio de rotação. Liberar um bloqueio de rotação adquirido com NdisReleaseSpinLock simplesmente permite que outro thread de execução adquira esse bloqueio de rotação.

Para obter mais informações sobre como adquirir e liberar bloqueios de rotação do NDIS, consulte Sincronização e notificação em drivers de rede.

Os chamadores de NdisAllocateSpinLock podem ser executados em qualquer IRQL. Normalmente, um chamador está em execução em IRQL = PASSIVE_LEVEL durante a inicialização.

Requisitos

Requisito Valor
Cliente mínimo com suporte Com suporte para drivers NDIS 6.0 e NDIS 5.1 (consulte NdisAllocateSpinLock (NDIS 5.1)) no Windows Vista. Com suporte para drivers NDIS 5.1 (consulte NdisAllocateSpinLock (NDIS 5.1)) no Windows XP.
Plataforma de Destino Universal
Cabeçalho ndis.h (inclua Ndis.h)
Biblioteca Ndis.lib
IRQL Qualquer nível (consulte a seção Comentários)
Regras de conformidade da DDI SpinLockDpr(ndis), SpinLockDprRelease(ndis), SpinlockRelease(ndis)

Confira também

DriverEntry de drivers de protocolo NDIS

MiniportDisableInterruptEx

MiniportHaltEx

MiniportInitializeEx

MiniportInterrupt

NdisAcquireSpinLock

NdisDprAcquireSpinLock

NdisDprReleaseSpinLock

NdisFreeSpinLock

NdisInterlockedAddUlong

NdisInterlockedInsertHeadList NdisInterlockedInsertTailList NdisInterlockedRemoveHeadList NdisMSynchronizeWithInterruptEx

NdisReleaseSpinLock

NetTimerCallback