示例#1
0
bool dSceneGraph::HasLinkToRoot (dTreeNode* node)
{
	int stack;
	char parentEdge[D_GRAPH_MAX_STACK_DEPTH];
	dTreeNode* pool[D_GRAPH_MAX_STACK_DEPTH];

	pool[0] = node;
	stack = 1;

	int lru = GetLRU();
	node->GetInfo().SetLRU (lru);

	while (stack) {
		stack --;
		node = pool[stack];
		if (node == m_rootNode) {
			return true;
		}

		int index = 0;
		for (index = stack - 1; (index >= 0) && parentEdge[index]; index --);
		if ((index >= 0) && !parentEdge[index]) {
			index ++;
			_ASSERTE (index <= stack);
		}
		
		for (dGraphNode::dLink::dListNode* link = node->GetInfo().m_children.GetFirst(); link; link = link->GetNext()){
			dGraphNode& info = link->GetInfo()->GetInfo();
			if (info.GetLRU() != lru) {

				info.SetLRU(lru);
				if (index >= 0) {
					pool[stack] = pool[index];
					parentEdge[stack] = parentEdge[index];

					pool[index] = link->GetInfo();
					parentEdge[index] = 0;
					index ++;
				} else {
					pool[stack] = link->GetInfo();
					parentEdge[stack] = 0;
				}
				stack ++;
				_ASSERTE (stack < (sizeof (parentEdge) / sizeof (parentEdge[0])));
			}
		}

		for (dGraphNode::dLink::dListNode* link = node->GetInfo().m_parents.GetFirst(); link; link = link->GetNext()){
			dGraphNode& info = link->GetInfo()->GetInfo();
			if (info.GetLRU() != lru) {
				info.SetLRU(lru);
				pool[stack] = link->GetInfo();
				parentEdge[stack] = 1;
				stack ++;
				_ASSERTE (stack < (sizeof (parentEdge) / sizeof (parentEdge[0])));
			}
		}
	}
	return false;
}
示例#2
0
/*============================================================================
**
** Function Name:       Read
**
** Visibility:          Public
**
** Description:         Read data from the cache. On a miss, 
**                      identifies LRU and evicts the data prior to reading data 
**                      from next lower level memory.
**
** Invocation:          By the CPU of adjecent memory hierarchy.
**
** Input Parameters:    const UINT32 address, 
**
** Return Values:       UINT8 data
**                      
**==========================================================================*/
UINT8 CCacheWriteThru::Read(const UINT32 address)
{
	// Separate tag, index and offset bits
    UINT32 offset = GetOffsetBits(address);
    UINT32 index = GetIndexBits(address);
    UINT32 tag = GetTagBits(address);
    
    UINT32 way_to_read = WAY_INVALID;
	
    // The byte to be returned
    UINT8 data = 0xFF;
    
    // Starting address of a line. 
    // Useful for reading a line from next memory hierarchy.
    UINT32 line_start_add;

#ifdef __debug__
    std::cout << std::endl << "--------------------------------------------------------" << std::endl;
    std::cout << " Address =  " << std::hex << address << std::dec << " Set No = " << index << std::endl;
#endif

	// Make sure sets exists
    if(m_sets)
    {
        // All is well
        way_to_read = MatchTagBits(m_sets[index], tag);

		if(WAY_INVALID != way_to_read)
        {
            // Cache Read hit. Yay!
            // Do nothing
            m_hits++;

#ifdef __debug__
std::cout << "Cache Read Hit. " << " Way to read = " << way_to_read << std::endl;         
#endif
        }
        else
        {
			UINT32 empty_way = GetEmptyWay(m_sets[index]);
            if(empty_way != WAY_INVALID)
            {
                // The set is not full, an empty way has been found
                m_misses++;
                way_to_read = empty_way;

#ifdef __debug__
    std::cout << "Cache miss. Set not full. " << " Way to read = " << way_to_read << std::endl;         
#endif
            }
            else
            {
                // The set is full
                // Cache read miss
                m_misses++;

                UINT32 way_lru = GetLRU(m_sets[index]);
                
                way_to_read = way_lru;

            } // if(empty_way == WAY_INVALID)

            // Need to read new cache line from L2 (Common to Is there an empty way, Conflict / Compulsory misses)
            line_start_add = (m_sets[index].lines[way_to_read].tag << (m_num_offset_bits + m_num_index_bits)) |
                                (index << m_num_offset_bits);

            for(UINT32 item_offset = 0; item_offset < m_line_size; item_offset++)
            {
                m_sets[index].lines[way_to_read].line_data[item_offset] = m_next_mem->Read(line_start_add + item_offset);
            }

		} // if(WAY_INVALID == way_to_read)

		// Get the requested byte and update the state bits
		data = m_sets[index].lines[way_to_read].line_data[offset];
        m_sets[index].lines[way_to_read].valid = 1;
        m_sets[index].lines[way_to_read].tag = tag;

        m_num_reads++;
		UpdateLRU(m_sets[index],way_to_read);

#ifdef __debug__
        printf("Data Read = %x\n", data); 
        std::cout << std::dec << "Stats: Total Reads = " << m_num_reads << " Total Writes = " << m_num_writes << std::endl;         
        std::cout << "Stats: Total Hits = " << m_hits << " Total Misses = " << m_misses << std::endl; 
        for(UINT32 item_offset = 0; item_offset < m_line_size; item_offset++)
        {
            printf("\n Line data %d = %x ", item_offset, m_sets[index].lines[way_to_read].line_data[item_offset]);
        }
#endif

	}
	else
	{
	// Sets not allocated!! SERIOUS ERROR!!!
        
	}

	return data;

}
示例#3
0
/*============================================================================
**
** Function Name:       Write
**
** Visibility:          Public
**
** Description:         Write data into the cache. Writes through to second 
**                      level memory to maintain inclusivity. On a miss, 
**                      identifies LRU and evicts the data prior to reading data 
**                      from next lower level memory
**
** Invocation:          By the CPU or adjecent memory hierarchy.
**
** Input Parameters:    const UINT32 address, const UINT8 data
**
** Return Values:       CACHE_HM // Cache hit or miss info
**                      
**==========================================================================*/
CACHE_HM CCacheWriteThru::Write(const UINT32 address, const UINT8 data)
{
    CACHE_HM hm_type = CACHE_HIT;

    // Separate Tag, index, offset bits
    UINT32 offset = GetOffsetBits(address);
    UINT32 index = GetIndexBits(address);
    UINT32 tag = GetTagBits(address);
    
    UINT32 way_to_write = WAY_INVALID;
    
    // Starting address of a line. 
    // Useful for reading a line from next memory hierarchy.
    UINT32 line_start_add;

#ifdef __debug__
    std::cout << std::endl << "--------------------------------------------------------" << std::endl;
    std::cout << " Address =  " << std::hex << address << " Data = " << data << std::dec << " Set No = " << index << std::endl;
#endif
    // Make sure sets exists
    if(m_sets)
    {
        // All is well
        way_to_write = MatchTagBits(m_sets[index], tag);
            
        if(WAY_INVALID != way_to_write)
        {
            // Cache write hit
            // Do nothing
            m_hits++;
            hm_type = CACHE_HIT;
#ifdef __debug__
std::cout << "Cache Hit. " << " Way to write = " << way_to_write << std::endl;         
#endif
        }
        else
        {
            UINT32 empty_way = GetEmptyWay(m_sets[index]);
            if(empty_way != WAY_INVALID)
            {
                // The set is not full
                m_misses++;
                hm_type = CACHE_MISS;
                way_to_write = empty_way;

#ifdef __debug__
    std::cout << "Cache miss. Set not full. " << " Way to write = " << way_to_write << std::endl;         
#endif
            }
            else
            {
                // The set is full
                // Cache write miss
                m_misses++;
                hm_type = CACHE_MISS;

                UINT32 way_lru = GetLRU(m_sets[index]);
                
                way_to_write = way_lru;
        

            }// if(WAY_INVALID == way_to_write)

            // Need to read new cache line from L2. Common to compuslory and confilct misses
            line_start_add = (m_sets[index].lines[way_to_write].tag << (m_num_offset_bits + m_num_index_bits)) |
                                        (index << m_num_offset_bits);

            for(UINT32 item_offset = 0; item_offset < m_line_size; item_offset++)
            {
                m_sets[index].lines[way_to_write].line_data[item_offset] = m_next_mem->Read(line_start_add + item_offset);
            }

        }

        m_sets[index].lines[way_to_write].line_data[offset] = data;

        // Need to write to next memeory hierarchy (L2) to maintain inclusivity

        line_start_add = (m_sets[index].lines[way_to_write].tag << (m_num_offset_bits + m_num_index_bits)) |
                                    (index << m_num_offset_bits);

        // No need to write the whole line, since we write only one byte at time.
        m_next_mem->Write(address, data);
      
        m_sets[index].lines[way_to_write].valid = 1;
        m_sets[index].lines[way_to_write].tag = tag;

        m_num_writes++;

        UpdateLRU(m_sets[index],way_to_write);
#ifdef __debug__
        std::cout << "Stats: Total Reads = " << m_num_reads << " Total Writes = " << m_num_writes << std::endl;         
        std::cout << "Stats: Total Hits = " << m_hits << " Total Misses = " << m_misses << std::endl;
        for(UINT32 item_offset = 0; item_offset < m_line_size; item_offset++)
        {
            printf("\n Line data %d = %x ", item_offset, m_sets[index].lines[way_to_write].line_data[item_offset]);
        }
#endif


    }
    else
    {
        // Sets not allocated!! SERIOUS ERROR!!!
        hm_type = hm_type;
    }

    return hm_type;

}
示例#4
0
void dSceneGraph::DeleteNode (dTreeNode* node)
{
	dList<dTreeNode*> conectedNodes;
	dTree<dTreeNode*, unsigned> deleteList;
	dGraphNode& info = node->GetInfo();
	deleteList.Insert(node, node->GetKey());

	while (info.m_parents.GetFirst()) {
		dTreeNode* const twinNode = info.m_parents.GetFirst()->GetInfo();

		conectedNodes.Append (twinNode);
		dGraphNode& twinInfo = twinNode->GetInfo();
		for (dGraphNode::dLink::dListNode* link = twinInfo.m_children.GetFirst(); link; link = link->GetNext()){
			if (link->GetInfo() == node) {
				twinInfo.m_children.Remove (link);
				break;
			}
		}
		for (dGraphNode::dLink::dListNode* link = twinInfo.m_parents.GetFirst(); link; link = link->GetNext()){
			if (link->GetInfo() == node) {
				twinInfo.m_parents.Remove (link);
				break;
			}
		}
		info.m_parents.Remove(info.m_parents.GetFirst());
	}

	
	while (info.m_children.GetFirst()) {
		dTreeNode* const twinNode = info.m_children.GetFirst()->GetInfo();

		conectedNodes.Append (twinNode);
		dGraphNode& twinInfo = twinNode->GetInfo();
		for (dGraphNode::dLink::dListNode* link = twinInfo.m_children.GetFirst(); link; link = link->GetNext()){
			if (link->GetInfo() == node) {
				twinInfo.m_children.Remove (link);
				break;
			}
		}
		for (dGraphNode::dLink::dListNode* link = twinInfo.m_parents.GetFirst(); link; link = link->GetNext()){
			if (link->GetInfo() == node) {
				twinInfo.m_parents.Remove (link);
				break;
			}
		}
		info.m_children.Remove(info.m_children.GetFirst());
	}

	
	for (dList<dTreeNode*>::dListNode* ptr = conectedNodes.GetFirst(); ptr; ptr = ptr->GetNext()){
		//char parentEdge[D_GRAPH_MAX_STACK_DEPTH];
		dTreeNode* pool[D_GRAPH_MAX_STACK_DEPTH];
		
		int stack = 1;
		int lru = GetLRU();
		pool[0] = ptr->GetInfo();
		node->GetInfo().SetLRU (lru);
		bool listIsDangling = true;
		dList<dTreeNode*> danglingNodes;

		while (stack) {
			stack --;
			dTreeNode* const node = pool[stack];
			if (node == m_rootNode) {
				listIsDangling = false;
				break;
			}
			danglingNodes.Append(node);

			for (dGraphNode::dLink::dListNode* link = node->GetInfo().m_children.GetFirst(); link; link = link->GetNext()){
				dGraphNode& info = link->GetInfo()->GetInfo();

				if (info.GetLRU() != lru) {
					info.SetLRU(lru);
					pool[stack] = link->GetInfo();
					stack ++;
					_ASSERTE (stack < (sizeof (pool) / sizeof (pool[0])));
				}
			}

			for (dGraphNode::dLink::dListNode* link = node->GetInfo().m_parents.GetFirst(); link; link = link->GetNext()){
				dGraphNode& info = link->GetInfo()->GetInfo();

				if (info.GetLRU() != lru) {
					info.SetLRU(lru);
					pool[stack] = link->GetInfo();
					stack ++;
					_ASSERTE (stack < (sizeof (pool) / sizeof (pool[0])));
				}
			}
		}

		if (listIsDangling) {
			for (dList<dTreeNode*>::dListNode* first = danglingNodes.GetFirst(); first; first = first->GetNext()) {
				deleteList.Insert(first->GetInfo(), first->GetInfo()->GetKey());
			}
		}
		danglingNodes.RemoveAll();
	}

	dTree<dTreeNode*, unsigned>::Iterator iter (deleteList);
	for (iter.Begin(); iter; iter ++) {
		dTreeNode* node = (*iter);
		if (Find(node->GetKey())) {
			dGraphNode& info = node->GetInfo();
			info.m_parents.RemoveAll();
			info.m_children.RemoveAll();
			info.m_nodeInfo->Release();
			info.m_nodeInfo = NULL;
			Remove (node);
		}
	}

}