Partilhar via


Multiprocessor-Safe

O sistema operativo baseado no Microsoft Windows NT foi projetado para ser executado de forma uniforme em plataformas de uniprocessador e de multiprocessador simétrico (SMP), e os drivers de modo kernel devem ser projetados para fazer o mesmo.

Em qualquer plataforma multiprocessador Windows, existem as seguintes condições:

  • Todas as CPUs são idênticas e todos ou nenhum dos processadores deve ter coprocessadores idênticos.

  • Todas as CPUs partilham memória e têm acesso uniforme à memória.

  • Em uma plataforma simétrica , cada CPU pode acessar a memória, fazer uma interrupção e acessar registradores de controle de E/S. (Por outro lado, numa máquina multiprocessador assimétrica, uma CPU recebe todas as interrupções para todo um conjunto de CPUs subordinadas.)

Para ser executado com segurança em uma plataforma SMP, um sistema operacional deve garantir que o código executado em um processador não acesse e modifique simultaneamente os dados que outro processador está acessando e modificando. Por exemplo, se o ISR de um driver de nível mais baixo estiver lidando com uma interrupção de dispositivo em um processador, ele deverá ter acesso exclusivo a registros de dispositivos ou dados críticos definidos pelo driver, caso seu dispositivo interrompa simultaneamente em outro processador.

Além disso, as operações de E/S dos drivers que são serializadas em um sistema uniprocessador podem ocorrer simultaneamente em um sistema SMP. Ou seja, a rotina de um driver que processa solicitações de E/S recebidas pode ser executada em um processador, enquanto outra rotina que se comunica com o dispositivo é executada simultaneamente em outro processador. Quer os drivers de modo kernel estejam sendo executados em uma máquina uniprocessador ou multiprocessador simétrica, eles devem sincronizar o acesso a quaisquer dados definidos pelo driver ou recursos fornecidos pelo sistema que são compartilhados entre as rotinas do driver e sincronizar o acesso ao dispositivo físico, se houver.

O componente kernel do Windows NT exporta um mecanismo de sincronização, chamado de spin lock, que os drivers podem usar para proteger dados partilhados (ou registos de dispositivo) do acesso simultâneo por uma ou mais rotinas que estão a ser executadas em simultâneo numa plataforma multiprocessadora simétrica. O kernel impõe duas políticas em relação ao uso de bloqueios de rotação:

  • Apenas uma rotina pode segurar um bloqueio de rotação específico a qualquer momento. Antes de acessar os dados compartilhados, cada rotina que deve fazer referência aos dados deve primeiro tentar adquirir o bloqueio de rotação dos dados. Para acessar os mesmos dados, outra rotina deve adquirir o bloqueio de rotação, mas o bloqueio de rotação não pode ser adquirido até que o titular atual o libere.

  • O kernel atribui um valor IRQL a cada bloqueio de rotação no sistema. Uma rotina de modo kernel pode adquirir um bloqueio de rotação específico somente quando a rotina é executada no IRQL atribuído ao bloqueio de rotação.

Essas políticas impedem que uma rotina de driver que geralmente é executada em um IRQL mais baixo, mas atualmente mantém um bloqueio de rotação, seja antecipada por uma rotina de driver de prioridade mais alta que está tentando adquirir o mesmo bloqueio de rotação. Assim, evita-se um impasse.

O IRQL que é atribuído a um bloqueio de rotação é geralmente o da rotina de IRQL mais alta que pode adquirir o bloqueio de rotação.

Por exemplo, o ISR de um controlador de nível inferior frequentemente compartilha uma área de estado com a rotina de DPC do controlador. A rotina do DPC chama uma rotina de seção crítica fornecida pelo driver para acessar a área compartilhada. O bloqueio de rotação que protege a área compartilhada tem um IRQL igual ao DIRQL no qual o dispositivo interrompe. Enquanto a rotina de seção crítica mantiver o bloqueio de rotação e acessar a área compartilhada no DIRQL, o ISR não poderá ser executado numa máquina uniprocessadora ou SMP.

  • O ISR não pode ser executado em uma máquina uniprocessadora porque a interrupção do dispositivo é suprimida, conforme descrito em Sempre Preemptível e Sempre Interrompível.

  • Em uma máquina SMP, o ISR não pode adquirir o bloqueio de rotação que protege os dados compartilhados, enquanto a rotina de seção crítica mantém o bloqueio de rotação e acessa os dados compartilhados no DIRQL.

Um conjunto de threads de modo kernel pode sincronizar o acesso a dados ou recursos compartilhados aguardando um dos objetos dispatcher do kernel: um evento, mutex, semáforo, temporizador ou outro thread. No entanto, a maioria dos drivers não configura seus próprios threads porque eles têm melhor desempenho quando evitam switches de contexto de thread. Sempre que rotinas de suporte de modo kernel críticas e drivers são executados em IRQL = DISPATCH_LEVEL ou em DIRQL, eles devem usar os bloqueios de rotação do kernel para sincronizar o acesso a dados ou recursos compartilhados.

Para obter mais informações, consulte Spin Locks, Managing Hardware Priorities e Kernel Dispatcher Objects.