Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
O objetivo do design preemptible e interruptível do sistema operacional é maximizar o desempenho do sistema. Qualquer thread pode ser preemptada por uma thread com uma prioridade mais alta, e a rotina de serviço de interrupção (ISR) de qualquer driver pode ser interrompida por uma rotina executada em um nível de solicitação de interrupção (IRQL) mais alto.
O componente kernel determina quando uma sequência de código é executada, de acordo com um destes critérios de priorização:
O esquema de prioridade de tempo de execução definido pelo kernel para threads.
Cada thread no sistema tem um atributo de prioridade associado. Em geral, a maioria das threads tem atributos de prioridade variável: elas são sempre preemptíveis e têm o seu tempo de execução distribuído de forma alternada com todas as outras threads que estão atualmente no mesmo nível de prioridade. Algumas tarefas têm atributos de prioridade em tempo real: as tarefas críticas para o tempo são executadas até à conclusão, a menos que sejam antecipadas por uma tarefa que tenha um atributo de prioridade em tempo real mais alto. A arquitetura do Microsoft Windows não fornece um sistema inerentemente em tempo real.
Seja qual for o seu atributo de prioridade, qualquer thread no sistema pode ser preemptado quando ocorrem interrupções de hardware e certos tipos de interrupções de software.
O nível de solicitação de interrupção definido pelo kernel (IRQL) ao qual um vetor de interrupção específico é atribuído em uma determinada plataforma.
O kernel prioriza interrupções de hardware e software para que algum código de modo kernel, incluindo a maioria dos drivers, seja executado em IRQLs mais altos, fazendo com que ele tenha uma prioridade de agendamento maior do que outros threads no sistema. O IRQL específico no qual uma parte do código de driver de modo kernel é executado é determinado pela prioridade de hardware de seu dispositivo subjacente.
O código do modo kernel é sempre interruptível: uma interrupção com um valor IRQL mais alto pode ocorrer a qualquer momento, fazendo com que outra parte do código do modo kernel que tenha um IRQL atribuído pelo sistema mais alto seja executada imediatamente nesse processador. No entanto, quando um pedaço de código é executado em um determinado IRQL, o kernel mascara todos os vetores de interrupção com um valor de IRQL menor ou igual no processador.
O nível mais baixo de IRQL é chamado de PASSIVE_LEVEL. Neste nível, nenhum vetor de interrupção é mascarado. Os threads geralmente são executados em IRQL=PASSIVE_LEVEL. Os próximos níveis mais altos de IRQL são para interrupções de software. Esses níveis incluem APC_LEVEL, DISPATCH_LEVEL ou, para depuração do kernel, WAKE_LEVEL. As interrupções de dispositivo têm valores de IRQL ainda mais altos. O kernel reserva os valores IRQL mais elevados para interrupções de importância crítica, como as provenientes do relógio do sistema ou erros de bus.
Algumas rotinas de suporte do sistema são executadas em IRQL=PASSIVE_LEVEL, seja porque são implementadas como código paginável ou acesso a dados pagináveis, ou porque alguns componentes do modo kernel configuram seus próprios threads.
Da mesma forma, algumas rotinas de driver padrão geralmente são executadas em IRQL=PASSIVE_LEVEL. No entanto, várias rotinas de driver padrão são executadas em IRQL=DISPATCH_LEVEL ou, para um driver de nível mais baixo, no dispositivo IRQL (também chamado de DIRQL). Para obter mais informações sobre IRQLs, consulte Gerenciando prioridades de hardware.
Toda rotina em um motorista é interruptível. Isso inclui qualquer rotina que esteja sendo executada em um IRQL mais alto do que PASSIVE_LEVEL. Qualquer rotina que esteja sendo executada em um IRQL específico mantém o controle do processador somente se nenhuma interrupção para um IRQL superior ocorrer enquanto essa rotina estiver em execução.
Ao contrário dos drivers em alguns sistemas operativos de computadores pessoais mais antigos, a ISR de um driver do Microsoft Windows nunca é uma rotina grande e complexa que realiza a maior parte do processamento de E/S do driver. Isso ocorre porque a rotina de serviço de interrupção (ISR) de qualquer driver pode ser interrompida por outra rotina (por exemplo, pelo ISR de outro driver) que é executada em um IRQL mais alto. Assim, o ISR do driver não necessariamente mantém o controle de uma CPU, ininterruptamente, desde o início de seu caminho de execução até o final.
Nos controladores do Windows, um ISR normalmente salva informações de estado de hardware, enfileira uma chamada de procedimento adiada (DPC) e, em seguida, sai rapidamente. Mais tarde, o sistema retira o DPC do driver para que o driver possa concluir as operações de E/S num nível de IRQL (DISPATCH_LEVEL) mais baixo. Para um bom desempenho geral do sistema, todas as rotinas que são executadas em altos IRQLs devem renunciar ao controle da CPU rapidamente.
No Windows, todos os encadeamentos têm um contexto de encadeamento. Esse contexto consiste em informações que identificam o processo proprietário do thread, além de outras características, como os direitos de acesso do thread.
Em geral, apenas um driver de nível mais alto é chamado no contexto do thread que está solicitando a operação de E/S atual do driver. Um driver de nível intermediário ou de nível mais baixo nunca pode assumir que está sendo executado no contexto do thread que solicitou sua operação de E/S atual.
Consequentemente, as rotinas de controlador geralmente são executadas em um contexto de thread arbitrário — o contexto de qualquer thread atual quando uma rotina de controlador padrão é invocada. Por razões de desempenho (para evitar opções de contexto), muito poucos drivers configuram seus próprios threads.