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 [2020/08/05 14:38] – maziero | so:gerente_de_disco [2024/07/03 14: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]] |