Nesse laboratório vamos explorar o uso de corotinas.
corotinas.h
) para criar duas corotinas bem simples,
chamadas "ping" e "pong".
Cada uma delas, quando ativada, imprime "ping" ou "pong", respectivamente,
e o valor recebido como argumento,
e devolve o controle, retornando o valor de um contador (variável local).
O programa principal deve ter um loop onde ativa alternadamente cada uma
dessas corotinas (cada passada no loop ativa uma delas), passando sempre para
a corotina o valor do contador do loop, e em seguida imprime o valor retornado
por coro_resume
.
Uma saída exemplo desse programa seria:
ping 0 main: 0 pong 1 main: 0 ping 2 main: 1 pong 3 main: 1 ...obs: Para compilar seu programa, use
gcc -m32 -Wa,--execstack -o meuprog meuprog.c core.s corotinas.c.
function create_task(f) -- cria uma tarefa local co = coroutine.create(f) table.insert(tasks, co) end function dispatcher() -- escalonador de tarefas local i = 1 while true do if tasks[i] == nil then if tasks[1] == nil then break end i= 1 end local status = coroutine.resume(tasks[i]) if status == false then table.remove(tasks, i) else i= i + 1 end end endVamos agora traduzir essa ideia para C. Várias mudanças terão que ser feitas: a primeira é que a estrutura de dados que armazena tarefas será uma lista encadeada. Pegue o arquivo com o esqueleto do programa. Esse esqueleto já contém as funções de manipulação da lista e a rotina
main
.
A função main
cria algumas corotinas para executarem a função
boba
, insere-as na lista encadeada, e em seguida ativa (chamar)
o dispatcher
.
Escreva a função dispatcher
, que
executa as corotinas presentes na lista.
Escreva uma função boba
que receba um único parâmetro, um int
,
que irá representar o número da tarefa.
boba
deve conter um loop com chamadas à função mostra
,
que recebe dois inteiros, o número da tarefa e o valor de um contador (uma variável
local, como em ping
e pong
.).
(O número da tarefa está armazenado no nó da lista que descreve a tarefa
e deve ser passado como parâmetro na chamada a coro_resume
,
juntamente com o descritor da corotina).
Note que quem faz o yield
nessas tarefas é a função mostra
,
que sempre devolve o valor 0, para indicar que a tarefa ainda está ativa.
Sua tarefa (função boba), ao terminar, deve retornar o valor 1, para o dispatcher
saber que ela acabou.