Partilhar via


Multiprocessor-Safe

O sistema operacional baseado em Windows NT da Microsoft foi projetado para ser executado uniformemente em plataformas uniprocessador e SMP (multiprocessador simétrico), e os drivers do modo kernel devem ser projetados para fazer o mesmo.

Em qualquer plataforma multiprocessador do 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 compartilham 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 registros de controle de E/S. (Por outro lado, em um computador multiprocessador assimétrico , uma CPU usa todas as interrupções para 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 tratando uma interrupção de dispositivo em um processador, ele deverá ter acesso exclusivo a registros de dispositivo 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 serializadas em um computador uniprocessador podem ser sobrepostas em um computador SMP. Ou seja, a rotina de um driver que processa solicitações de E/S de entrada pode ser executada em um processador, enquanto outra rotina que se comunica com o dispositivo é executada simultaneamente em outro processador. Se os drivers do modo kernel estão sendo executados em um computador uniprocessador ou multiprocessador simétrico, eles devem sincronizar o acesso a quaisquer dados definidos pelo driver ou recursos fornecidos pelo sistema que sejam compartilhados entre rotinas de driver e sincronizar o acesso ao dispositivo físico, se houver.

O componente de kernel Windows NT exporta um mecanismo de sincronização, chamado de bloqueio de rotação, que os drivers podem usar para proteger dados compartilhados (ou registros de dispositivo) contra acesso simultâneo por uma ou mais rotinas que estão sendo executadas simultaneamente em uma plataforma multiprocessador simétrica. O kernel impõe duas políticas relacionadas ao uso de bloqueios de rotação:

  • Apenas uma rotina pode manter um bloqueio de rotação específico a qualquer momento. Antes de acessar dados compartilhados, cada rotina que deve referenciar os 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 os 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 do bloqueio de rotação.

Essas políticas impedem que uma rotina de driver que geralmente é executada em um IRQL inferior, mas atualmente impede que um bloqueio de rotação seja precedido por uma rotina de driver de prioridade mais alta que está tentando adquirir o mesmo bloqueio de rotação. Portanto, um deadlock é evitado.

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

Por exemplo, o ISR de um driver de nível mais baixo frequentemente compartilha uma área de estado com a rotina de DPC do driver. A rotina 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. Desde que a rotina de seção crítica mantenha o bloqueio de rotação e acesse a área compartilhada em DIRQL, o ISR não pode ser executado em um computador uniprocessador ou SMP.

  • O ISR não pode ser executado em um computador uniprocessador porque a interrupção do dispositivo é mascarada, conforme descrito em Always Preemptible e Always Interruptible.

  • Em um computador 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 no 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 opções de contexto de thread. Sempre que o modo kernel crítico de tempo dá suporte a rotinas e drivers executados em IRQL = DISPATCH_LEVEL ou no 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.