コード例 #1
0
ファイル: cache.cpp プロジェクト: AXLEproject/nvram-sim
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);
}
コード例 #2
0
ファイル: cache.cpp プロジェクト: AXLEproject/nvram-sim
void
Cache :: line_writer_to_sharer(Line *line, size_t &latency, bool children_only)
{
    // make this cache (and child caches)
    // only sharers of the line (downgrade from a writer)
    NVLOG1("%s\tline_writer_to_sharer 0x%lx +%ld cycles\n", this->_name.c_str(), line->addr, _hit_latency);
    latency += _hit_latency;
    this->stats.writebacks_inc();
    for (size_t child_i = 0; child_i<_children.size(); 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())
        {
            if (line_addr_iter!=line->addr) {
                // also measure the latency for other line segments
                NVLOG1("%s\tline_writer_to_sharer 0x%lx +%ld cycles\n", this->_name.c_str(), line_addr_iter, _hit_latency);
                latency += _hit_latency;  // response from child to parent
                this->stats.writebacks_inc();
            }
            Line *child_line = child->addr2line_internal(line_addr_iter);
            if (!child_line) continue;
            child->line_writer_to_sharer(child_line, latency);
        }
    }
    if (!children_only) {
        this->line_data_writeback(line);
        line->state &= ~(LINE_MOD | LINE_EXC);
        line->state |= LINE_SHR;
    }
    NVLOG1("%s\t0x%lx\t new state %s sharers %lx\n",  _name.c_str(),  line->addr,  state2str(line->state).c_str(), line->sharers );
}
コード例 #3
0
ファイル: cache.cpp プロジェクト: AXLEproject/nvram-sim
void
Cache :: line_rm_recursive(Addr addr)
{
    Line *line = addr2line_internal(addr);
    if (line==NULL) return;
    NVLOG1("%s\tline_rm_recursive addr 0x%lx\n", this->_name.c_str(), addr);
    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()) {
            child->line_rm_recursive(line_addr_iter);
        }
    }
#ifdef HAS_HTM
    if (pprocessor) {
        pprocessor->cb_line_evicted(line);
    }
#endif
    free(line->pdata);
    line->pdata = NULL;
    // remove in this cache as well
    this->line_rm(line);
}
コード例 #4
0
ファイル: cache.cpp プロジェクト: AXLEproject/nvram-sim
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;
}