====== Tarefas suspensas ======
:!: alterações na interface em 03/2023, nome mudou de ''task_join'' para ''task_wait''
{{ :so:ppos_08_join.mkv |Video deste projeto}}
O objetivo deste projeto é construir funções para suspender e acordar tarefas. A principal função a implementar é ''task_wait'', que permite a uma tarefa suspender-se para esperar a conclusão de outra, de forma similar às chamadas POSIX ''wait'' e ''pthread_join'':
int task_wait (task_t *task)
A chamada ''task_wait (b)'' faz com que a tarefa atual (corrente) seja suspensa até a conclusão da tarefa ''b''. Mais tarde, quando a tarefa ''b'' encerrar (usando a chamada ''task_exit''), a tarefa suspensa deve retornar à fila de tarefas prontas. Lembre-se que várias tarefas podem ficar aguardando que a tarefa ''b'' encerre, então todas elas têm de ser acordadas quando isso ocorrer.
Caso a tarefa ''b'' não exista ou já tenha encerrado, esta chamada deve retornar imediatamente, sem suspender a tarefa atual.
O valor de retorno da chamada ''task_wait'' deve ser o código de encerramento da tarefa ''b'' (valor ''exit_code'' informado como parâmetro de ''task_exit''), ou -1, caso a tarefa indicada não exista ou algum outro erro.
Sua implementação deverá funcionar com {{pingpong-wait.c|este código}} e gerar uma saída similar a {{pingpong-wait.txt|este exemplo}}.
Use o controle de preempção para evitar condições de disputa nas variáveis envolvidas.
===== Suspender e retomar =====
Para facilitar a construção deste e dos próximos projetos, deve-se implementar as funções ''task_suspend'' e ''task_awake'' descritos a seguir:
void task_suspend (task_t **queue) ;
Suspende a **tarefa atual** através das seguintes ações:
- retira a tarefa atual da fila de tarefas prontas (se estiver nela);
- ajusta o status da tarefa atual para "suspensa";
- insere a tarefa atual na fila apontada por ''queue'' (se essa fila não for nula);
- retorna ao //dispatcher//.
void task_awake (task_t * task, task_t **queue) ;
Acorda uma tarefa que está suspensa em uma dada fila, através das seguintes ações:
- se a fila ''queue'' não for nula, retira a tarefa apontada por ''task'' dessa fila;
- ajusta o status dessa tarefa para "pronta";
- insere a tarefa na fila de tarefas prontas;
- continua a tarefa atual (**não retorna** ao //dispatcher//)
Juntas, essas duas funções simplificam suspender e reativar tarefas, sem precisar manipular diretamente a fila de tarefas prontas.
===== Outras informações =====
* Duração estimada: 4 horas.
* Dependências:
* [[Gestão de Tarefas]]
* [[Dispatcher]]
* [[Preempção por Tempo]]