diff -r d1f8610cdffd -r 1af0000a8d03 src/mem/ruby/network/MessageBuffer.hh --- a/src/mem/ruby/network/MessageBuffer.hh Fri Jan 15 11:30:13 2016 +0000 +++ b/src/mem/ruby/network/MessageBuffer.hh Sun Jan 17 17:46:38 2016 -0600 @@ -135,9 +135,32 @@ // sorted and ensures a well-defined iteration order typedef std::map > StallMsgMapType; + /** + * A map from line addresses to lists of stalled messages for that line. + * If this buffer allows the receiver to stall messages, on a stall + * request, the stalled message is removed from the m_prio_heap and placed + * in the m_stall_msg_map. Messages are held there until the receiver + * requests they be reanalyzed, at which point they are moved back to + * m_prio_heap. + */ StallMsgMapType m_stall_msg_map; + /** + * Current size of the stall map. + * Track the number of messages held in stall map lists. This is used to + * ensure that if the buffer is finite-sized, it blocks further requests + * when the m_prio_heap and m_stall_msg_map contain m_max_size messages. + */ + int m_stall_map_size; + + /** + * The maximum capacity. For finite-sized buffers, m_max_size stores a + * number greater than 0 to indicate the maximum allowed number of messages + * in the buffer at any time. To get infinitely-sized buffers, set buffer + * size: m_max_size = 0 + */ const unsigned int m_max_size; + Tick m_time_last_time_size_checked; unsigned int m_size_last_time_size_checked; diff -r d1f8610cdffd -r 1af0000a8d03 src/mem/ruby/network/MessageBuffer.cc --- a/src/mem/ruby/network/MessageBuffer.cc Fri Jan 15 11:30:13 2016 +0000 +++ b/src/mem/ruby/network/MessageBuffer.cc Sun Jan 17 17:46:38 2016 -0600 @@ -40,7 +40,7 @@ using m5::stl_helpers::operator<<; MessageBuffer::MessageBuffer(const Params *p) - : SimObject(p), + : SimObject(p), m_stall_map_size(0), m_max_size(p->buffer_size), m_time_last_time_size_checked(0), m_time_last_time_enqueue(0), m_time_last_time_pop(0), m_last_arrival_time(0), m_strict_fifo(p->ordered), @@ -100,7 +100,7 @@ } // now compare the new size with our max size - if (current_size + n <= m_max_size) { + if (current_size + m_stall_map_size + n <= m_max_size) { return true; } else { DPRINTF(RubyQueue, "n: %d, current_size: %d, heap size: %d, " @@ -290,6 +290,8 @@ // scheduled for the current cycle so that the previously stalled messages // will be observed before any younger messages that may arrive this cycle // + m_stall_map_size -= m_stall_msg_map[addr].size(); + assert(m_stall_map_size >= 0); reanalyzeList(m_stall_msg_map[addr], current_time); m_stall_msg_map.erase(addr); } @@ -307,6 +309,8 @@ // for (StallMsgMapType::iterator map_iter = m_stall_msg_map.begin(); map_iter != m_stall_msg_map.end(); ++map_iter) { + m_stall_map_size -= map_iter->second.size(); + assert(m_stall_map_size >= 0); reanalyzeList(map_iter->second, current_time); } m_stall_msg_map.clear(); @@ -328,6 +332,7 @@ // these addresses change state. // (m_stall_msg_map[addr]).push_back(message); + m_stall_map_size++; } void