Cache de blocos

Este projeto faz parte do PPOS v2.

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:

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:

Essa função faz a leitura de blocos usando o cache, da seguinte forma:

  1. procura o bloco no cache
  2. se encontrou o bloco
    1. copia conteúdo do cache para o buffer (usando mem_copy)
  3. senão
    1. lê o bloco do disco (usando block_read)
    2. obtém uma entrada livre no cache (ou libera uma)
    3. copia o conteúdo do bloco lido para o cache
  4. atualiza a data de acesso daquele bloco no cache

Escrita de bloco com cache

int cache_write (int block, void* buffer) ;

Parâmetros:

Essa função faz a escrita de blocos usando o cache, da seguinte forma:

  1. se o bloco não estiver no cache ainda
    1. obtém uma entrada livre no cache (ou libera uma)
  2. copia o conteúdo do bloco no cache (usando mem_copy)
  3. atualiza a data de acesso daquele bloco no cache
  4. 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:

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