Despachante de tarefas

:!: alterações na interface em 03/2023

Vídeo deste projeto

Você irá construir um despachante de tarefas baseado em duas entidades: uma tarefa dispatcher, responsável pelo controle geral, e uma função scheduler, responsável por determinar qual a próxima tarefa a executar a cada troca de contexto. A figura abaixo ilustra o funcionamento geral do sistema:

A seguinte chamada para a execução da tarefa atual e retorna ao dispatcher:

void task_yield () ;

O que deve fazer essa função:

  1. coloca a tarefa atual no fim da fila de prontas
  2. muda o estado da tarefa atual para PRONTA
  3. devolve a CPU ao despachante
Sugestão: use a função task_switch() para implementar task_yield().

Observações

O código do corpo da tarefa dispatcher deve seguir +/- o seguinte modelo (simplificado):

função dispatcher
início
   // retira o dispatcher da fila de prontas, para evitar que ele ative a si próprio
   queue_remove (...)

   // enquanto houverem tarefas de usuário
   enquanto ( userTasks > 0 )

      // escolhe a próxima tarefa a executar
      próxima = scheduler ()

      // escalonador escolheu uma tarefa?      
      se próxima ≠ NULO então

         // transfere controle para a próxima tarefa
         task_switch (próxima)
         
         // voltando ao dispatcher, trata a tarefa de acordo com seu estado
         caso o estado da tarefa "próxima" seja:
            PRONTA    : ...
            TERMINADA : ...
            SUSPENSA  : ...
            (etc)
         fim caso         

      fim se

   fim enquanto

   // encerra a tarefa dispatcher
   task_exit(0)
fim

Sua implementação deve funcionar com este código. A saída da execução deve ser igual a este exemplo.

Outras informações