Para tentar sanar um pouco as dúvidas dos alunos em cima de polling e interrupções aqui vai uma breve explicação sobre o assunto. Vale a pena lembrar que os exemplos a seguir estão disponíveis nos códigos-fonte do kernel do Linux.

Cada vez que um dispositivo do computador recebe um comando, como por exemplo, “buscar informações no setor 43 da fita DAT” o driver de dispositivo deve ter como descobrir que esse comando de busca foi concluído. Os drivers de dispositivo podem consultar o dispositivo (através de polling) ou eles podem usar interrupções.

Executar polling em um dispositivo normalmente significa ler seu registrador de estado tantas vezes for necessário, até que este indique não está mais em uso, para assim poder receber uma requisição. Como um driver de dispositivo é parte do kernel seria desastroso se um determinado driver, ao ser requisitado bloqueasse qualquer outra rotina no kernel até que este driver terminasse de ser utilizado.

Ao invés de usar a técnica de polling em dispositivos, o uso de timers (temporizadores) do sistema é mais prático, já que o kernel chama uma determinada rotina dentro do driver de dispositivo depois de algum tempo, impedindo que o mesmo fique bloqueado indefinidamente, e mantendo um pouco de previsibilidade. Esta rotina do timer iria verificar o estado do comando e isso é exatamente como funciona o driver de disco no Linux.

Polling por meio de timers é um método muito eficaz porém é muito mais eficiente a utilização de interrupções para tratar as requisições do computador. A interrupção é um recurso de hardware que os  dispositivos utilizam para indicar sempre que precisar ser utilizado.

Por exemplo, um dispositivo de rede, interromperia sempre que recebesse um pacote da rede. O kernel do Linux deve ser capaz de entregar a interrupção do dispositivo de hardware para o dispositivo correto, evitando que o dispositivo de rede fique bloqueado. Consegue-se isso através do registro do uso do driver do dispositivo com o kernel. Este registra o endereço de uma rotina de manipulação da interrupção e o número da interrupção que deseja possuir. O usuário pode ver qual interrupção está sendo usada pelo driver de dispositivo, bem como quantos tipos de interrupções existem acessando o arquivo /proc/interrupts:

cat /proc/interrupts

A saída é:

0:      727432   timer
1:       20534   keyboard
2:           0   cascade
3:       79691 + serial
4:       28258 + serial
5:           1   sound blaster
11:      20868 + aic7xxx
13:          1   math error
14:        247 + ide0
15:        170 + ide1

Essa requisição do recurso de interrupção é feita no momento de inicialização do driver. Observe o código a seguir que mostra que o kernel habilita uma flag chamada ok, caso esta esteja disponível para executar, muda seu valor e aguarda a interrupção de acordo com o número que lhe foi atribuído.

static int try_one_irq(int irq, struct irq_desc *desc)
 {
          struct irqaction *action;
          int ok = 0, work = 0;

          raw_spin_lock(&desc->lock);
          if (desc->status & IRQ_INPROGRESS) {
                  if (desc->action && (desc->action->flags & IRQF_SHARED))
                          desc->status |= IRQ_PENDING;
                  raw_spin_unlock(&desc->lock);
                  return ok;
          }
          /* Honour the normal IRQ locking */
          desc->status |= IRQ_INPROGRESS;
          action = desc->action;
          raw_spin_unlock(&desc->lock);

          while (action) {
                  /* Only shared IRQ handlers are safe to call */
                  if (action->flags & IRQF_SHARED) {
                          if (action->handler(irq, action->dev_id) == IRQ_HANDLED)
                                  ok = 1;
                  }
                  action = action->next;
          }

Algumas interrupções tem números fixos, isso é um legado da arquitetura do IBM PC :D. Então por exemplo, uma controladora de disquetes sempre usa a interrupção de número 6. Outras interrupções, por exemplo, como as dos dispositivos PCI, são alocadas dinamicamente no momento do boot do sistema operacional. Nesse caso o driver de dispositivo, deve primeiro descobrir o número da interrupção (IRQ) do dispositivo que está controlando, antes que este requisite prioritariamente uma interrupção.

Interrupções não são as únicas formas de interromper um programa em execução. Pode utilizar as exceções ou traps. Mais informações clique aqui.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 

Post Navigation