# Node ID e6fd9419eacf7997c838d228f192324cd84fb978 # Parent fd85445fafbe0e6571028aeb62a2df4af5be1326 diff --git a/src/mem/ruby/network/MessageBuffer.cc b/src/mem/ruby/network/MessageBuffer.cc --- a/src/mem/ruby/network/MessageBuffer.cc +++ b/src/mem/ruby/network/MessageBuffer.cc @@ -297,17 +297,17 @@ } void -MessageBuffer::reanalyzeList(list <, Tick nextTick) +MessageBuffer::reanalyzeList(list <, Tick schdTick) { while(!lt.empty()) { m_msg_counter++; - MessageBufferNode msgNode(nextTick, m_msg_counter, lt.front()); + MessageBufferNode msgNode(schdTick, m_msg_counter, lt.front()); m_prio_heap.push_back(msgNode); push_heap(m_prio_heap.begin(), m_prio_heap.end(), greater()); - m_consumer->scheduleEventAbsolute(nextTick); + m_consumer->scheduleEventAbsolute(schdTick); lt.pop_front(); } } @@ -317,13 +317,15 @@ { DPRINTF(RubyQueue, "ReanalyzeMessages\n"); assert(m_stall_msg_map.count(addr) > 0); - Tick nextTick = m_receiver->clockEdge(Cycles(1)); + Tick curTick = m_receiver->clockEdge(); // // Put all stalled messages associated with this address back on the - // prio heap + // prio heap. The reanalyzeList call will make sure the consumer is + // scheduled for the current cycle so that the previously stalled messages + // will be observed before any younger messages that may arrive this cycle // - reanalyzeList(m_stall_msg_map[addr], nextTick); + reanalyzeList(m_stall_msg_map[addr], curTick); m_stall_msg_map.erase(addr); } @@ -331,15 +333,17 @@ MessageBuffer::reanalyzeAllMessages() { DPRINTF(RubyQueue, "ReanalyzeAllMessages\n"); - Tick nextTick = m_receiver->clockEdge(Cycles(1)); + Tick curTick = m_receiver->clockEdge(); // // Put all stalled messages associated with this address back on the - // prio heap + // prio heap. The reanalyzeList call will make sure the consumer is + // scheduled for the current cycle so that the previously stalled messages + // will be observed before any younger messages that may arrive this cycle. // for (StallMsgMapType::iterator map_iter = m_stall_msg_map.begin(); map_iter != m_stall_msg_map.end(); ++map_iter) { - reanalyzeList(map_iter->second, nextTick); + reanalyzeList(map_iter->second, curTick); } m_stall_msg_map.clear(); } @@ -350,7 +354,7 @@ DPRINTF(RubyQueue, "Stalling due to %s\n", addr); assert(isReady()); assert(addr.getOffset() == 0); - MsgPtr message = m_prio_heap.front().m_msgptr; + MessageBufferNode node = m_prio_heap.front(); dequeue(); @@ -359,7 +363,7 @@ // Instead the controller is responsible to call reanalyzeMessages when // these addresses change state. // - (m_stall_msg_map[addr]).push_back(message); + (m_stall_msg_map[addr]).push_back(node.m_msgptr); } void diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -150,6 +150,7 @@ std::map m_block_map; typedef std::vector MsgVecType; + typedef std::set MsgBufType; typedef std::map< Address, MsgVecType* > WaitingBufType; WaitingBufType m_waiting_buffers; diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc --- a/src/mem/ruby/slicc_interface/AbstractController.cc +++ b/src/mem/ruby/slicc_interface/AbstractController.cc @@ -155,6 +155,7 @@ // std::vector wokeUpMsgVecs; + MsgBufType wokeUpMsgBufs; if(m_waiting_buffers.size() > 0) { for (WaitingBufType::iterator buf_iter = m_waiting_buffers.begin(); @@ -163,8 +164,13 @@ for (MsgVecType::iterator vec_iter = buf_iter->second->begin(); vec_iter != buf_iter->second->end(); ++vec_iter) { - if (*vec_iter != NULL) { + // + // Make sure the MessageBuffer has not already be reanalyzed + // + if (*vec_iter != NULL && + (wokeUpMsgBufs.count(*vec_iter) == 0)) { (*vec_iter)->reanalyzeAllMessages(); + wokeUpMsgBufs.insert(*vec_iter); } } wokeUpMsgVecs.push_back(buf_iter->second);