====== Cache de blocos ====== Este projeto tem por objetivo implementar um cache em memória RAM para os blocos lidos e/ou escritos no disco. ===== O problema ===== O acesso a disco é uma operação demorada, pois o disco é lento. Para melhorar o desempenho, pode-se guardar uma cópia em RAM dos blocos lidos ou escritos no disco, para agilizar acessos futuros. As estratégias de //caching// a implementar neste projeto são as seguintes: * //Read-through//: ao **ler um bloco** do disco, guarda-se uma cópia dele no cache em RAM; **futuras leituras** devem consultar o cache para ver se o conteúdo do bloco desejado está nele. * //Write-through//: ao **escrever um bloco** no disco, guarda-se uma cópia do mesmo no cache em RAM; **futuras leituras** devem consultar o cache para ver se o conteúdo do bloco desejado está nele nele. Este projeto implementa um cache com escrita //síncrona//, que é mais simples. Em um cache com escrita assíncrona (ou //write-back cache//), as tarefas escreveriam somente no cache, deixando a atualização do bloco no disco para uma tarefa específica de gestão de cache. O cache pode ser visto como um vetor ou lista de blocos com capacidade limitada, geralmente inferior ao tamanho do disco. Se ele estiver cheio e um novo bloco precisar ser armazenado, outro bloco deverá ser descartado do cache antes. Neste projeto, deve-se usar o algoritmo LRU (//Least-Recently Used//) para escolher o bloco a descartar do cache. Em outras palavras, quando for necessário remover um bloco do cache, deve ser removido aquele que **está há mais tempo no cache sem ser acessado**. ===== Interface de acesso ao cache ===== O acesso ao cache de disco pelas tarefas é feito através das funções definidas em ''kernel/cache.h'' e implementadas (pelo aluno) em ''kernel/cache.c'': === Iniciar o subsistema === void cache_init(); Esta função, chamada na inicialização do PPOS (em ''kernel/ppos.c'') inicia o subsistema de cache de disco. === Leitura de bloco com cache === int cache_read (int block, void* buffer) ; Parâmetros: * ''block'': número do bloco a ler do disco (entre 0 e //número de blocos// - 1); * ''buffer'': endereço do //buffer// onde devem ser colocados os dados lidos do disco; esse //buffer// deve ter capacidade para ''block_size'' bytes. * retorno: 0 em caso de sucesso ou -1 em caso de erro. Essa função faz a leitura de blocos usando o cache, da seguinte forma: - procura o bloco no cache - se encontrou o bloco - copia conteúdo do cache para o buffer (usando ''mem_copy'') - senão - lê o bloco do disco (usando ''block_read'') - obtém uma entrada livre no cache (ou libera uma) - copia o conteúdo do bloco lido para o cache - atualiza a data de acesso daquele bloco no cache === Escrita de bloco com cache === int cache_write (int block, void* buffer) ; Parâmetros: * ''block'': número do bloco a escrever no disco (entre 0 e //número de blocos// - 1); * ''buffer'': endereço do //buffer// com os dados a escrever no disco; esse //buffer// deve ter capacidade para ''block_size'' bytes. * retorno: 0 em caso de sucesso ou -1 em caso de erro. Essa função faz a escrita de blocos usando o cache, da seguinte forma: - se o bloco não estiver no cache ainda - obtém uma entrada livre no cache (ou libera uma) - copia o conteúdo do bloco no cache (usando ''mem_copy'') - atualiza a data de acesso daquele bloco no cache - escreve o bloco no disco (usando ''block_write'') === A implementação ===== Este projeto usa como base o projeto de [[acesso ao disco]] desenvolvido anteriormente. Neste projeto você deve: * Implementar as funções de acesso ao cache; * Implementar a política LRU, para liberar entradas se o cache estiver cheio; * Gerenciar a exclusão mútua no acesso ao cache. Existe o risco de que duas tarefas tentem acessar/atualizar a mesma entrada do cache simultaneamente, o que pode levar à corrupção dos dados ou do cache. Isso deve ser evitado com semáforos. ===== Outras informações ===== * Duração estimada: 4 horas. * Dependências: * [[Tarefas cooperativas]] * [[Despachante de tarefas]] * [[Preempção por Tempo]] * [[Tarefas que esperam]] * [[Tarefas que dormem]] * [[Spinlocks e Semáforos]] * [[Acesso ao disco]]