]> wirehaze git hosting - ppos.git/blob - ppos/test/pingpong-mqueue.c

wirehaze git hosting

tasks implementation (ongoing)
[ppos.git] / ppos / test / pingpong-mqueue.c
1 // PingPongOS - PingPong Operating System
2 // Prof. Carlos A. Maziero, DINF UFPR
3 // Versão 2.0 -- Junho de 2025
4
5 // ATENÇÃO: ESTE ARQUIVO NÃO DEVE SER ALTERADO;
6 // ALTERAÇÕES SERÃO DESCARTADAS NA CORREÇÃO.
7
8 // Teste das filas de mensagens
9
10 #include <assert.h>
11 #include "lib/libc.h"
12 #include "ppos.h"
13
14 // estrutura com vários valores para teste
15 struct pacote_t
16 {
17 int v[3], prod;
18 };
19
20 static struct task_t *prod[3], *mult, *cons[2];
21 static struct mqueue_t *fila_inteiros, *fila_pacotes;
22
23 // corpo da tarefa produtor
24 void body_prod()
25 {
26 int valor, status;
27 char *name;
28
29 name = task_name(NULL);
30
31 printf("%5d ms: %s inicia\n", systime(), name);
32
33 for (;;)
34 {
35 // sorteia um valor inteiro e o envia na fila de valores
36 valor = 1 + randnum() % 20;
37 status = mqueue_send(fila_inteiros, &valor);
38 if (status < 0)
39 break;
40 printf("%5d ms: %s envia %d\n", systime(), name, valor);
41
42 // dorme um intervalo aleatorio
43 task_sleep(randnum() % 3000);
44 }
45
46 printf("%5d ms: %s termina\n", systime(), name);
47 task_exit(0);
48 }
49
50 // corpo da tarefa agrupador
51 void body_agrup()
52 {
53 struct pacote_t pacote;
54 char *name;
55 int status;
56
57 name = task_name(NULL);
58
59 printf("%5d ms: \t\t\t%s inicia\n", systime(), name);
60
61 for (int i = 0; i < 10; i++)
62 {
63 // recebe N valores inteiros e os põe no pacote
64 pacote.prod = 1 ;
65 for (int j = 0; j < 3; j++)
66 {
67 status = mqueue_recv(fila_inteiros, &pacote.v[j]);
68 assert(status == NOERROR);
69
70 printf("%5d ms: \t\t\t%s recebe %d\n", systime(), name,
71 pacote.v[j]);
72 pacote.prod *= pacote.v[j] ;
73 }
74
75 // mostra o pacote
76 printf("%5d ms: \t\t\t%s envia [%d*%d*%d = %d]\n",
77 systime(), name, pacote.v[0], pacote.v[1], pacote.v[2],
78 pacote.prod);
79
80 // envia o pacote
81 status = mqueue_send(fila_pacotes, &pacote);
82 assert(status == NOERROR);
83
84 // dorme um intervalo aleatorio
85 task_sleep(randnum() % 3000);
86 }
87
88 printf("%5d ms: \t\t\t%s termina\n", systime(), name);
89 task_exit(0);
90 }
91
92 // corpo da tarefa consumidor
93 void body_cons()
94 {
95 struct pacote_t pacote;
96 char *name;
97 int status;
98
99 name = task_name(NULL);
100
101 printf("%5d ms: \t\t\t\t\t\t%s inicia\n", systime(), name);
102
103 for (;;)
104 {
105 // recebe um pacote e o imprime
106 status = mqueue_recv(fila_pacotes, &pacote);
107 if (status < 0)
108 break;
109 printf("%5d ms: \t\t\t\t\t\t%s recebe [%d*%d*%d = %d]\n",
110 systime(), name, pacote.v[0], pacote.v[1], pacote.v[2],
111 pacote.prod);
112
113 // dorme um intervalo aleatorio
114 task_sleep(randnum() % 3000);
115 }
116
117 printf("%5d ms: \t\t\t\t\t\t%s termina\n", systime(), name);
118 task_exit(0);
119 }
120
121 // corpo da tarefa principal
122 void user_main(void *arg)
123 {
124 int status;
125
126 printf("%5d ms: user inicia\n", systime());
127
128 // cria as filas de mensagens (5 valores cada)
129 fila_inteiros = mqueue_create(5, sizeof(int));
130 assert(fila_inteiros);
131 fila_pacotes = mqueue_create(5, sizeof(struct pacote_t));
132 assert(fila_pacotes);
133
134 // cria tarefas
135 mult = task_create("agrup", body_agrup, NULL);
136 assert(mult);
137 cons[0] = task_create("cons0", body_cons, NULL);
138 assert(cons[0]);
139 cons[1] = task_create("cons1", body_cons, NULL);
140 assert(cons[1]);
141 prod[0] = task_create("prod0", body_prod, NULL);
142 assert(prod[0]);
143 prod[1] = task_create("prod1", body_prod, NULL);
144 assert(prod[1]);
145 prod[2] = task_create("prod2", body_prod, NULL);
146 assert(prod[2]);
147
148 // aguarda o multiplicador encerrar
149 status = task_wait(mult);
150 assert(status == NOERROR);
151
152 // destroi as filas de mensagens
153 printf("%5d ms: user destroi fila_inteiros\n", systime());
154 status = mqueue_destroy(fila_inteiros);
155 assert(status == NOERROR);
156 printf("%5d ms: user destroi fila_pacotes\n", systime());
157 status = mqueue_destroy(fila_pacotes);
158 assert(status == NOERROR);
159
160 printf("%5d ms: user termina\n", systime());
161
162 task_exit(0);
163 }