static void cache_miss(struct cache *cache, enum access_type type, struct set *set, struct decoded_address *access_addr) { cache->miss_count[type]++; struct cache_entry *e = entry_to_evict(set); if ((e->flags & VALID) && (e->flags & DIRTY)) { // write the contents of the evicted address to the // next level cache struct decoded_address evict_addr; evict_addr.tag = e->tag; evict_addr.index = access_addr->index; evict_addr.offset = 0; cache->writeback_count++; cache_access(cache->next, WRITE_ACCESS, encode_address(&evict_addr, cache)); } cache_access(cache->next, READ_ACCESS, encode_address(access_addr, cache)); e->tag = access_addr->tag; e->age = 0; e->flags = VALID; if (type == WRITE_ACCESS) e->flags |= DIRTY; }
struct bcache_entry *bget(block_sector_t sec) { int i; struct clock_helper *temp; lock_acquire (&bcache_lock); bool in_evict = search_evict(sec); if (in_evict) thread_yield(); for (i=0; i < CACHE_SIZE; i++) { if( buffer_cache[i]->sec == sec) { lock_acquire (&buffer_cache[i]->block_lock); buffer_cache[i]->op_cnt++; lock_release(&bcache_lock); lock_release (&buffer_cache[i]->block_lock); return buffer_cache[i]; } } for (i=0; i < CACHE_SIZE; i++) { if(! buffer_cache[i]->used) { lock_acquire (&buffer_cache[i]->block_lock); buffer_cache[i]->sec = sec; buffer_cache[i]->op_cnt++; buffer_cache[i]->used = true; temp = malloc (sizeof(struct clock_helper)); temp->sec = sec; if (first) { clock_ptr = temp; list_push_back (&clock_list, &temp->elem); first = false; } else list_insert (&clock_ptr->elem, &temp->elem); lock_release(&bcache_lock); lock_release (&buffer_cache[i]->block_lock); return buffer_cache[i]; } } // not found, needs eviction struct bcache_entry *to_evict = entry_to_evict(); lock_acquire (&to_evict->block_lock); block_sector_t sec_old = to_evict->sec; to_evict->sec = sec; temp = get_helper_by_sec (sec_old); temp->sec = sec; lock_release(&bcache_lock); if (to_evict->dirty) { struct evicting_entry *e = malloc (sizeof(struct evicting_entry)); e->sec = sec_old; list_push_back (&evict_list, &e->elem); block_write (fs_device, sec_old, to_evict->buffer); list_remove (&e->elem); free(e); } block_read (fs_device, to_evict->sec, to_evict->buffer); to_evict->op_cnt++; lock_release(&to_evict->block_lock); return to_evict; }