Example #1
0
void
Cache :: line_evict(Line *line)
{
    NVLOG1("%s\tline_evict addr 0x%lx data 0x%lx\n", this->_name.c_str(), line->addr, (Addr)line->pdata);
    // evict in all child caches
    for (size_t child_i = 0; child_i<_children.size() && line->sharers>0; child_i++) {
        if (!bit(line->sharers, child_i)) continue; // a child is not a sharer, so continue
        Cache *child = dynamic_cast<Cache *>(_children[child_i]); assert(child!=NULL);
        for (Addr line_addr_iter=line->addr; line_addr_iter<line->addr+get_line_size(); line_addr_iter += child->get_line_size()) {
            Line *child_line = child->addr2line_internal(line_addr_iter);
            if (child_line == NULL) continue;
            child->line_evict(child_line);
        }
    }
#ifdef HAS_HTM
    if (pprocessor) {
        pprocessor->cb_line_evicted(line);
    }
#endif
    if (!_parent_cache) {
	// notify the processor of the line removal
#ifdef HAS_HTM
	assert(pprocessor);
	pprocessor->cb_line_evicted(line);
#endif
    }
    this->line_data_writeback(line); // check if there is any data to writeback

    free(line->pdata);
    line->pdata = NULL;
    // remove in this cache as well
    this->line_rm(line);
}
Example #2
0
bool
Cache :: line_make_owner_in_child_caches(Line *line, unsigned child_index)
{
    NVLOG1("%s\tline_make_owner_in_child_caches 0x%lx sharers %lx caller %d\n", this->_name.c_str(), line->addr, line->sharers, child_index);
    uint8_t __attribute__((unused)) line_state_orig = line->state;
    uint64_t __attribute__((unused)) line_sharers_orig = line->sharers;
    // evict the line in all but the requesting child cache
    for (size_t child_i = 0; child_i<_children.size() && line->sharers>0; child_i++) {
        Cache *child = dynamic_cast<Cache *>(_children[child_i]); assert(child!=NULL);
        // NVLOG1("%s\tchecking for 0x%lx %lx 1\n", child->_name.c_str(), line->addr, line->sharers);
        if (!bit(line->sharers, child_i)) continue; // a child is not a sharer, so continue
        // NVLOG1("%s\tchecking for 0x%lx %lx 2\n", child->_name.c_str(), line->addr, line->sharers);
        if (child_i == child_index) continue; // skip the child cache that called us
        // NVLOG1("%s\tchecking for 0x%lx %lx 3\n", child->_name.c_str(), line->addr, line->sharers);
        for (Addr line_addr_iter=line->addr; line_addr_iter<line->addr+get_line_size(); line_addr_iter += child->get_line_size())
        {
            NVLOG1("%s\tis line sharer, checking segment 0x%lx\n", child->_name.c_str(), line_addr_iter);
            Line *child_line = child->addr2line_internal(line_addr_iter);
            if (!child_line) continue;
            NVLOG1("%s\thas segment 0x%lx, evicting\n", child->_name.c_str(), line_addr_iter);
            child->line_evict(child_line);
        }
    }
    line->sharers = 0;
    setbit(line->sharers, child_index);
    NVLOG1("%s\tline 0x%lx\t state %s->%s sharers 0x%lx->0x%lx\n",  _name.c_str(),  line->addr,  state2str(line_state_orig).c_str(), state2str(line->state).c_str(), line_sharers_orig, line->sharers);
    return true;
}