예제 #1
0
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;
}
예제 #2
0
파일: cache.c 프로젝트: koroder/PintOS
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;

}