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().
  • O dispatcher deve ser implementado como uma tarefa, a ser iniciada usando a chamada task_init durante a inicialização do sistema (execução de ppos_init).
  • O programa principal inicia todas as tarefas de usuário e passa o controle para a tarefa dispatcher, que só encerra quando não existirem mais tarefas de usuário a executar.
  • Será necessário implementar uma fila de tarefas prontas, usando a biblioteca de filas genéricas desenvolvida anteriormente.
  • A política de escalonamento será definida por uma função scheduler(), chamada pelo dispatcher para decidir qual a próxima tarefa a ativar. Neste projeto, deve ser implementada uma política FCFS.
  • Quando uma tarefa encerrar, o controle volta ao dispatcher e este libera as estruturas de dados alocadas para a tarefa.
  • quando o dispatcher encerrar, a chamada task_exit deve encerrar o programa chamando exit.

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.

  • so/dispatcher.txt
  • Última modificação: 2024/02/14 15:17
  • por maziero