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

wirehaze git hosting

add ppos/
[ppos.git] / ppos / test / pingpong-disco-stress.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 operações de acesso a disco com múltiplas tarefas
9 // fazendo operações de leitura e escrita simultâneas.
10
11 #include <assert.h>
12 #include "lib/libc.h"
13 #include "ppos.h"
14
15 #define NUMTASKS 8
16
17 // tarefas
18 static struct task_t *mover[NUMTASKS]; // tarefas movedoras de blocos
19 static int num_blk; // numero de blocos no disco
20 static int blk_size; // tamanho de cada bloco (bytes)
21
22 // lê um bloco do disco
23 void le_bloco(int task, int block, char *buffer)
24 {
25 int status;
26
27 printf("%5d ms: T%-2d lendo bloco %3d\n", systime(), task, block);
28 status = block_read(block, buffer);
29 if (status == 0)
30 printf("%5d ms: T%-2d leu bloco %3d\n", systime(), task, block);
31 else
32 printf("%5d ms: T%-2d erro ao ler bloco %3d\n", systime(), task, block);
33 }
34
35 // escreve um bloco no disco
36 void escreve_bloco(int task, int block, char *buffer)
37 {
38 int status;
39
40 printf("%5d ms: T%-2d escrevendo bloco %3d\n", systime(), task, block);
41 status = block_write(block, buffer);
42 if (status == 0)
43 printf("%5d ms: T%-2d escreveu bloco %3d\n", systime(), task, block);
44 else
45 printf("%5d ms: T%-2d erro ao escrever bloco %3d\n",
46 systime(), task, block);
47 }
48
49 // mostra o conteudo do bloco
50 void mostra_bloco(int task, int block, char *buffer)
51 {
52 printf("%5d ms: T%-2d bloco %3d tem: [", systime(), task, block);
53 for (int j = 0; j < blk_size; j++)
54 printf("%c", buffer[j]);
55 printf("]\n");
56 }
57
58 // corpo das tarefas "mover"
59 void body(void *arg)
60 {
61 int my_id, blk_orig, blk_dest;
62 int tid, blk_per_task;
63 char *buf1, *buf2;
64
65 tid = task_id(NULL);
66 blk_per_task = (num_blk / NUMTASKS / 2);
67
68 // aloca espaço para os buffers
69 buf1 = mem_alloc(blk_size);
70 assert(buf1);
71 buf2 = mem_alloc(blk_size);
72 assert(buf2);
73
74 // define os blocos iniciais
75 my_id = (long)arg;
76 blk_orig = my_id * blk_per_task;
77 blk_dest = num_blk - 1 - (my_id * blk_per_task);
78
79 printf("%5d ms: T%-2d movendo %2d blocos entre blocos %3d e %3d\n",
80 systime(), tid, blk_per_task, blk_orig, blk_dest);
81
82 // move blk_per_task blocos
83 for (int i = 0; i < blk_per_task; i++)
84 {
85 // lê dois blocos do disco
86 le_bloco(tid, blk_orig, buf1);
87 le_bloco(tid, blk_dest, buf2);
88
89 // mostra o conteudo dos blocos
90 mostra_bloco(tid, blk_orig, buf1);
91 mostra_bloco(tid, blk_dest, buf2);
92
93 // escreve os blocos trocados no disco
94 escreve_bloco(tid, blk_dest, buf1);
95 escreve_bloco(tid, blk_orig, buf2);
96
97 // define os próximos blocos
98 blk_orig++;
99 blk_dest--;
100 }
101 printf("%5d ms: T%-2d terminou\n", systime(), tid);
102
103 mem_free(buf1);
104 mem_free(buf2);
105 task_exit(0);
106 }
107
108 // corpo da tarefa principal
109 void user_main(void *arg)
110 {
111 int status;
112
113 printf("user: inicio\n");
114
115 // busca geometria do disco
116 num_blk = block_blocks();
117 assert(num_blk);
118 blk_size = block_size();
119 assert(blk_size);
120
121 printf("%5d ms: disco contem %d blocos de %d bytes cada\n",
122 systime(), num_blk, blk_size);
123
124 // cria as tarefas
125 for (long i = 0; i < NUMTASKS; i++)
126 {
127 mover[i] = task_create(NULL, body, (void *)i);
128 assert(mover[i]);
129 }
130
131 // aguarda as tarefas encerrarem
132 for (int i = 0; i < NUMTASKS; i++)
133 {
134 status = task_wait(mover[i]);
135 assert(status == NOERROR);
136 }
137
138 // destroi os descritores
139 for (int i = 0; i < NUMTASKS; i++)
140 {
141 status = task_destroy(mover[i]);
142 assert(status == NOERROR);
143 }
144
145 printf("user: fim\n");
146
147 task_exit(0);
148 }