Partilhar via


Introdução às fechaduras giratórias

Os spinlocks são mecanismos de sincronização definidos pelo kernel, utilizados apenas no modo kernel, e são exportados como um tipo opaco: KSPIN_LOCK. Um bloqueio de rotação pode ser usado para proteger dados ou recursos compartilhados contra acesso simultâneo. Ao executar em IRQL <= DISPATCH_LEVEL, um driver pode usar KeAcquireInStackQueuedSpinLock e KeReleaseInStackQueuedSpinLock para adquirir e liberar o bloqueio de rotação como um bloqueio de rotação enfileirado .

Como alternativa, os chamadores que executam no IRQL >= DISPATCH_LEVEL podem chamar KeAcquireSpinLockAtDpcLevel e KeReleaseSpinLockFromDpcLevel para um melhor desempenho do driver.

Muitos componentes usam bloqueios de rotação, incluindo controladores. Qualquer tipo de controlador pode usar um ou mais bloqueios executivos de rotação . Por exemplo, a maioria dos sistemas de arquivos usa uma fila de trabalho interligada na extensão de dispositivo dos drivers do sistema de arquivos (FSD) para armazenar IRPs que são processados tanto pelas rotinas de retorno de chamada da thread de trabalho do sistema de arquivos quanto pelo próprio FSD. Uma fila de trabalho intertravada é protegida por um bloqueio de rotação executivo, que resolve a contenção entre o FSD tentando inserir IRPs na fila e quaisquer threads simultaneamente tentando remover IRPs. Como outro exemplo, o driver do controlador de disquete do sistema usa dois bloqueios de rotação executivos. Um bloqueio de rotação executivo protege uma fila de trabalho intertravada compartilhada com o thread dedicado ao dispositivo deste driver; o outro protege um objeto de temporizador compartilhado por três rotinas de driver.

Os bloqueios de rotação em fila oferecem melhor desempenho do que os bloqueios de rotação comuns para bloqueios de alta contenção em máquinas multiprocessadoras. Para obter mais informações, consulte Bloqueios de rotação em fila. Os drivers também podem usar KeAcquireSpinLock e KeReleaseSpinLock para adquirir e libertar um bloqueio de rotação como um bloqueio de rotação comum.

Para sincronizar o acesso a estruturas de dados simples, os drivers podem usar qualquer uma das rotinas ExInterlockedXxx para garantir o acesso atômico à estrutura de dados. Os drivers que usam essas rotinas não precisam adquirir ou liberar o bloqueio de rotação explicitamente.

Cada driver que tem um ISR usa um de bloqueio de rotação de interrupção para proteger quaisquer dados ou hardware compartilhados entre seu ISR e suas rotinas de SynchCritSection que são chamadas a partir de suas rotinas StartIo e DpcForIsr. Um bloqueio de rotação de interrupção está associado ao conjunto de objetos de interrupção criados quando o driver chama IoConnectInterrupt, conforme descrito em Registrando um ISR.

Siga estas diretrizes para usar bloqueios de rotação em drivers:

  • Forneça armazenamento para dados ou recursos protegidos por um bloqueio de rotação e para o bloqueio de rotação correspondente na memória residente do espaço do sistema (pool não paginado, conforme mostrado na figura Espaços de Memória Virtual e Memória Física). Um driver deve fornecer o armazenamento para quaisquer bloqueios de rotação executivos que ele usa. No entanto, um driver de dispositivo não precisa fornecer o armazenamento para um bloqueio de rotação de interrupção, a menos que tenha um ISR multivetorial ou tenha mais de um ISR, conforme descrito em Registrando um ISR.

  • Chame KeInitializeSpinLock para inicializar cada bloqueio de rotação para o qual o driver fornece armazenamento antes de usá-lo para sincronizar o acesso aos dados compartilhados ou recursos que ele protege.

  • Chame cada rotina de suporte que usa um bloqueio de rotação em um IRQL apropriado, geralmente em <= DISPATCH_LEVEL para bloqueios de rotação executivos ou em <= DIRQL para um bloqueio de rotação de interrupção associado aos objetos de interrupção do driver.

  • Implemente rotinas para executar o mais rápido possível enquanto elas seguram um bloqueio de rotação. Nenhuma rotina deve manter um bloqueio de rotação por mais de 25 microssegundos.

  • Nunca implemente rotinas que façam qualquer um dos seguintes procedimentos enquanto segura um bloqueio de rotação:

    • Provoque exceções de hardware ou levante exceções de software.

    • Tente acessar a memória paginável.

    • Faça uma chamada recursiva que cause um deadlock ou possa fazer com que um bloqueio de rotação seja mantido por mais de 25 microssegundos.

    • Tente adquirir outro bloqueio de rotação se isso puder causar um impasse.

    • Chame uma rotina externa que viole qualquer uma das regras anteriores.