Diferenças

Aqui você vê as diferenças entre duas revisões dessa página.

Link para esta página de comparações

Ambos lados da revisão anterior Revisão anterior
Próxima revisão
Revisão anterior
so:gestao_de_tarefas [2020/08/18 19:46] – edição externa 127.0.0.1so:gestao_de_tarefas [2024/02/14 08:30] (atual) maziero
Linha 1: Linha 1:
 +====== Gestão de Tarefas ======
 +
 +:!: alterações na interface em 03/2023 
 +
 +{{ :so:ppos_02_tarefas.mkv |Vídeo deste projeto}}
 +
 +**Objetivo**: construir as funções básicas de gestão de tarefas usando as funções de troca de contexto vistas no projeto anterior.
 +
 +===== Descritor de tarefa =====
 +
 +Cada tarefa existente no sistema deve ter uma estrutura que a representa, ou seja, um descritor de tarefa (//TCB - Task Control Block//). O tipo dessa estrutura deve ser definido no arquivo ''ppos_data.h'':
 +
 +<code c>
 +typedef struct task_t
 +{
 +   struct task_t *prev, *next ;   // para a biblioteca de filas (cast)
 +   int tid ;                      // task ID, identificador da tarefa
 +   int status ;                   // pronta, executando, terminada, ...
 +   ...                            // demais informações da tarefa
 +} task_t ;
 +</code>
 +
 +===== Interface =====
 +
 +As seguintes funções devem ser implementadas:
 +
 +=== Inicializa o sistema ===
 +
 +<code c>
 +void ppos_init ()
 +</code>
 +
 +Esta função inicializa as estruturas internas do SO. Por enquanto, conterá apenas algumas inicializações de variáveis e a seguinte instrução, que desativa o buffer utilizado pela função ''printf'', para evitar condições de disputa que podem ocorrer nesse buffer ao usar as funções de troca de contexto:
 +
 +<code c>
 +/* desativa o buffer da saida padrao (stdout), usado pela função printf */
 +setvbuf (stdout, 0, _IONBF, 0) ;
 +</code>
 +
 +=== Inicia uma nova tarefa ===
 +
 +<code c>
 +int task_init (task_t *task, void (*start_routine)(void *),  void *arg) 
 +</code>
 +
 +  * ''task'': estrutura que referencia a tarefa a ser iniciada
 +  * ''start_routine'': função que será executada pela tarefa
 +  * ''arg'': parâmetro a passar para a tarefa que está sendo iniciada
 +  * retorno: o ID (>0) da nova tarefa ou um valor negativo, se houver erro
 +
 +Atenção: deve ser previsto um descritor de tarefa que aponte para o programa principal (que exercerá a mesma função da variável ''ContextMain'' no programa ''contexts.c'').
 +
 +=== Transfere o processador para outra tarefa ===
 +
 +<code c>
 +int task_switch (task_t *task)
 +</code>
 +
 +  * ''task'': tarefa que irá assumir o processador
 +  * retorno: valor negativo se houver erro, ou zero
 +
 +Esta é a operação básica de troca de contexto, que encapsula a função ''swapcontext''. Ela será chamada sempre que for necessária uma troca de contexto.
 +
 +=== Termina a tarefa corrente ===
 +
 +{{ :so:cutting-off-branch.jpg|Cutting off a branch}}
 +
 +<code c>
 +void task_exit (int exit_code)
 +</code>
 +
 +  * ''exit_code'' : código de término devolvido pela tarefa corrente (ignorar este parâmetro por enquanto, pois ele somente será usado mais tarde).
 +
 +Neste projeto, quando uma tarefa encerra, o controle deve retornar à tarefa ''main''. Isso é feito usando usando ''task_switch''.
 +
 +=== Informa o identificador da tarefa corrente ===
 +
 +<code c>
 +int task_id ()
 +</code>
 +
 +  * retorno: Identificador numérico (ID) da tarefa corrente, que deverá ser 0 para ''main'', ou um valor positivo para as demais tarefas. Esse identificador é único: não devem existir duas tarefas com o mesmo ID.
 +
 +===== Observações =====
 +
 +A implementação completa deste projeto compreende definir os tipos e estruturas de dados necessários para gerenciar as tarefas e implementar as funções acima descritas, comentando detalhadamente o código.
 +
 +A convenção de estruturação de código em C deverá ser respeitada:
 +
 +  * ''ppos_data.h'': definições de dados globais (esqueleto: {{ppos_data.h}})
 +    * constantes e macros globais
 +    * definições dos tipos e estruturas de dados globais
 +  * ''ppos.h'': interface do SO (fornecido: {{ppos.h}}, **não alterar**)
 +    * protótipos das funções públicas
 +  * ''ppos_core.c'': contém as definições internas do sistema:
 +    * constantes e macros internas
 +    * definições dos tipos e estruturas de dados internas
 +    * funções internas
 +    * implementações das funções públicas
 +
 +<note important>
 +Capriche na implementação, pois esse código será a base de todos os projetos posteriores. Todos os avisos de compilação gerados com o flag ''-Wall'' serão **descontados**! 
 +</note>
 +
 +===== Validação =====
 +
 +Seu código deve funcionar adequadamente com os programas de teste abaixo indicados, fornecendo as saídas esperadas:
 +
 +  * {{pingpong-tasks1.c|programa de teste 1}} e sua {{pingpong-tasks1.txt|saída esperada}}
 +  * {{pingpong-tasks2.c|programa de teste 2}} e sua {{pingpong-tasks2.txt|saída esperada}}
 +  * {{pingpong-tasks3.c|programa de teste 3}} e sua {{pingpong-tasks3.txt|saída esperada}}
 +
 +<note tip>
 +O primeiro programa de teste corresponde ao código {{contexts.c}} do projeto anterior, reescrito com as novas funções. Comparar os dois códigos pode ajudar a compreender o que deve ser implementado em cada função.
 +</note>
 +
 +Compile da seguinte forma:
 +
 +<code>
 +$ cc -Wall ppos_core.c pingpong-tasks1.c
 +</code>
 +
 +Se desejar mais detalhes da compilação, pode usar o flag ''-Wextra'':
 + 
 +<code>
 +$ cc -Wextra ppos_core.c pingpong-tasks1.c
 +</code>
 +
 +===== Depuração =====
 +
 +Todas as funções implementadas devem gerar mensagens de depuração, que permitam acompanhar a execução das tarefas, como no exemplo a seguir:
 +
 +<code>
 +task_init: iniciada tarefa 23
 +task_switch: trocando contexto 14 -> 23
 +task_exit: tarefa 23 sendo encerrada
 +...
 +</code>
 +
 +Essas mensagens de depuração somente deverão ser geradas se a contante global ''DEBUG'' estiver definida, usando compilação condicional:
 +
 +<code c>
 +#ifdef DEBUG
 +printf ("task_init: iniciada tarefa %d\n", task->id) ;
 +#endif
 +</code>
 +
 +A constante ''DEBUG'' pode ser definida no código-fonte:
 +
 +<code c>
 +#define DEBUG
 +</code>
 +
 +ou na linha de comando, no momento da compilação:
 +
 +<code>
 +$ cc -Wall -o teste -DDEBUG ppos_core.c pingpong-tasks1.c
 +</code>
 +
 +===== Outras informações =====
 +
 +  * Duração estimada: 4 horas.
 +  * Dependências:
 +    * [[Trocas de contexto]]