Diferenças
Aqui você vê as diferenças entre duas revisões dessa página.
| Ambos lados da revisão anterior Revisão anterior Próxima revisão | Revisão anterior | ||
| so:gerente_de_disco [2023/03/29 14:30] – maziero | so:gerente_de_disco [2024/07/03 11:32] (atual) – [O disco virtual] maziero | ||
|---|---|---|---|
| Linha 1: | Linha 1: | ||
| + | ====== Gerente de disco ====== | ||
| + | {{ : | ||
| + | |||
| + | Este projeto tem por objetivo implementar operações de entrada/ | ||
| + | |||
| + | ===== Interface de acesso ao disco ===== | ||
| + | |||
| + | A tarefa principal ('' | ||
| + | |||
| + | <code c> | ||
| + | int disk_mgr_init (& | ||
| + | </ | ||
| + | |||
| + | Ao retornar da chamada, a variável '' | ||
| + | |||
| + | As tarefas podem ler e escrever blocos de dados no disco virtual através das seguintes chamadas (ambas bloqueantes): | ||
| + | |||
| + | <code c> | ||
| + | int disk_block_read | ||
| + | int disk_block_write (int block, void* buffer) ; | ||
| + | </ | ||
| + | |||
| + | * '' | ||
| + | * '' | ||
| + | * retorno: 0 em caso de sucesso ou -1 em caso de erro. | ||
| + | |||
| + | Cada tarefa que solicita uma operação de leitura/ | ||
| + | |||
| + | ===== O disco virtual ===== | ||
| + | |||
| + | O "disco virtual" | ||
| + | |||
| + | * O conteúdo do disco virtual é mapeado em um arquivo UNIX no diretório corrente da máquina real, com nome default '' | ||
| + | * O disco contém N blocos de mesmo tamanho. O número de blocos do disco dependerá do tamanho do arquivo subjacente no sistema real. | ||
| + | * Como em um disco real, as operações de leitura/ | ||
| + | * Os pedidos de leitura/ | ||
| + | * O disco só trata uma leitura/ | ||
| + | * O tempo de resposta do disco é proporcional à distância entre a posição atual da cabeça de leitura do disco e a posição da operação solicitada. Inicialmente a cabeça de leitura está posicionada sobre o bloco inicial (zero). | ||
| + | |||
| + | O código que simula o disco está em '' | ||
| + | |||
| + | <note warning> | ||
| + | O acesso ao disco deve feito **somente** através das definições presentes em '' | ||
| + | </ | ||
| + | |||
| + | Atenção: o arquivo '' | ||
| + | |||
| + | < | ||
| + | cc -Wall queue.c ppos_core.c ppos_disk.c disk.c pingpong-disco.c -lrt | ||
| + | </ | ||
| + | |||
| + | ===== Tarefa ===== | ||
| + | |||
| + | A gerência das operações de entrada/ | ||
| + | |||
| + | * Uma tarefa gerenciadora do disco; | ||
| + | * Uma função para tratar os sinais '' | ||
| + | * Uma fila de pedidos de acesso ao disco; cada pedido indica a tarefa solicitante, | ||
| + | * As funções de acesso ao disco oferecidas às tarefas ('' | ||
| + | |||
| + | A implementação do gerenciamento de disco deve ficar no arquivo '' | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | ===== Testes ===== | ||
| + | |||
| + | Sua implementação deverá funcionar com estes arquivos de teste: | ||
| + | |||
| + | * {{disk.dat}}: | ||
| + | * {{pingpong-disco1.c}}: | ||
| + | * {{pingpong-disco2.c}}: | ||
| + | |||
| + | ===== Sugestão de implementação ===== | ||
| + | |||
| + | A tarefa //gerente de disco// é responsável por tratar os pedidos de leitura/ | ||
| + | |||
| + | <code c> | ||
| + | void diskDriverBody (void * args) | ||
| + | { | ||
| + | while (true) | ||
| + | { | ||
| + | // obtém o semáforo de acesso ao disco | ||
| + | |||
| + | // se foi acordado devido a um sinal do disco | ||
| + | if (disco gerou um sinal) | ||
| + | { | ||
| + | // acorda a tarefa cujo pedido foi atendido | ||
| + | } | ||
| + | |||
| + | // se o disco estiver livre e houver pedidos de E/S na fila | ||
| + | if (disco_livre && (fila_disco != NULL)) | ||
| + | { | ||
| + | // escolhe na fila o pedido a ser atendido, usando FCFS | ||
| + | // solicita ao disco a operação de E/S, usando disk_cmd() | ||
| + | } | ||
| + | |||
| + | // libera o semáforo de acesso ao disco | ||
| + | |||
| + | // suspende a tarefa corrente (retorna ao dispatcher) | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | A tarefa gerente de disco deve ser acordada (voltar à fila de tarefas prontas) sempre que: | ||
| + | |||
| + | * alguma tarefa pedir uma operação de leitura/ | ||
| + | * o disco gerar um sinal indicando que a última operação solicitada foi concluída. | ||
| + | |||
| + | Dessa forma, as funções '' | ||
| + | |||
| + | <code c> | ||
| + | disk_block_read (block, & | ||
| + | { | ||
| + | // obtém o semáforo de acesso ao disco | ||
| + | |||
| + | // inclui o pedido na fila_disco | ||
| + | |||
| + | if (gerente de disco está dormindo) | ||
| + | { | ||
| + | // acorda o gerente de disco (põe ele na fila de prontas) | ||
| + | } | ||
| + | |||
| + | // libera semáforo de acesso ao disco | ||
| + | |||
| + | // suspende a tarefa corrente (retorna ao dispatcher) | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Outras informações ===== | ||
| + | |||
| + | * Duração estimada: 8 horas. | ||
| + | * Dependências: | ||
| + | * [[Gestão de Tarefas]] | ||
| + | * [[Dispatcher]] | ||
| + | * [[Preempção por Tempo]] | ||
| + | * [[Tarefas suspensas]] | ||
| + | * [[Tarefas dormindo]] | ||
| + | * [[Semáforos]] | ||