summaryrefslogtreecommitdiff
path: root/src/mem/ruby/buffers
diff options
context:
space:
mode:
authorNilay Vaish <nilay@cs.wisc.edu>2012-10-15 17:51:57 -0500
committerNilay Vaish <nilay@cs.wisc.edu>2012-10-15 17:51:57 -0500
commit5ffc16593997b35f4f1abbd149e01169e6bbcff5 (patch)
tree647411a3d027f2bdfaf750f65107affb6d9c002d /src/mem/ruby/buffers
parent07ce90f7aa28a507493da905ba1881972250bb3a (diff)
downloadgem5-5ffc16593997b35f4f1abbd149e01169e6bbcff5.tar.xz
ruby: improved support for functional accesses
This patch adds support to different entities in the ruby memory system for more reliable functional read/write accesses. Only the simple network has been augmented as of now. Later on Garnet will also support functional accesses. The patch adds functional access code to all the different types of messages that protocols can send around. These messages are functionally accessed by going through the buffers maintained by the network entities. The patch also rectifies some of the bugs found in coherence protocols while testing the patch. With this patch applied, functional writes always succeed. But functional reads can still fail.
Diffstat (limited to 'src/mem/ruby/buffers')
-rw-r--r--src/mem/ruby/buffers/MessageBuffer.cc66
-rw-r--r--src/mem/ruby/buffers/MessageBuffer.hh20
-rw-r--r--src/mem/ruby/buffers/MessageBufferNode.hh1
3 files changed, 79 insertions, 8 deletions
diff --git a/src/mem/ruby/buffers/MessageBuffer.cc b/src/mem/ruby/buffers/MessageBuffer.cc
index f0d372a52..f960cc033 100644
--- a/src/mem/ruby/buffers/MessageBuffer.cc
+++ b/src/mem/ruby/buffers/MessageBuffer.cc
@@ -435,3 +435,69 @@ MessageBuffer::printStats(ostream& out)
out << "MessageBuffer: " << m_name << " stats - msgs:" << m_msg_counter
<< " full:" << m_not_avail_count << endl;
}
+
+bool
+MessageBuffer::isReady() const
+{
+ return ((m_prio_heap.size() > 0) &&
+ (m_prio_heap.front().m_time <= g_system_ptr->getTime()));
+}
+
+bool
+MessageBuffer::functionalRead(Packet *pkt)
+{
+ // Check the priority heap and read any messages that may
+ // correspond to the address in the packet.
+ for (unsigned int i = 0; i < m_prio_heap.size(); ++i) {
+ Message *msg = m_prio_heap[i].m_msgptr.get();
+ if (msg->functionalRead(pkt)) return true;
+ }
+
+ // Read the messages in the stall queue that correspond
+ // to the address in the packet.
+ for (StallMsgMapType::iterator map_iter = m_stall_msg_map.begin();
+ map_iter != m_stall_msg_map.end();
+ ++map_iter) {
+
+ for (std::list<MsgPtr>::iterator it = (map_iter->second).begin();
+ it != (map_iter->second).end(); ++it) {
+
+ Message *msg = (*it).get();
+ if (msg->functionalRead(pkt)) return true;
+ }
+ }
+ return false;
+}
+
+uint32_t
+MessageBuffer::functionalWrite(Packet *pkt)
+{
+ uint32_t num_functional_writes = 0;
+
+ // Check the priority heap and write any messages that may
+ // correspond to the address in the packet.
+ for (unsigned int i = 0; i < m_prio_heap.size(); ++i) {
+ Message *msg = m_prio_heap[i].m_msgptr.get();
+ if (msg->functionalWrite(pkt)) {
+ num_functional_writes++;
+ }
+ }
+
+ // Check the stall queue and write any messages that may
+ // correspond to the address in the packet.
+ for (StallMsgMapType::iterator map_iter = m_stall_msg_map.begin();
+ map_iter != m_stall_msg_map.end();
+ ++map_iter) {
+
+ for (std::list<MsgPtr>::iterator it = (map_iter->second).begin();
+ it != (map_iter->second).end(); ++it) {
+
+ Message *msg = (*it).get();
+ if (msg->functionalWrite(pkt)) {
+ num_functional_writes++;
+ }
+ }
+ }
+
+ return num_functional_writes;
+}
diff --git a/src/mem/ruby/buffers/MessageBuffer.hh b/src/mem/ruby/buffers/MessageBuffer.hh
index cf7e77c2d..c4fd7165d 100644
--- a/src/mem/ruby/buffers/MessageBuffer.hh
+++ b/src/mem/ruby/buffers/MessageBuffer.hh
@@ -41,10 +41,10 @@
#include <string>
#include <vector>
+#include "mem/packet.hh"
#include "mem/ruby/buffers/MessageBufferNode.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Consumer.hh"
-#include "mem/ruby/common/Global.hh"
#include "mem/ruby/slicc_interface/Message.hh"
class MessageBuffer
@@ -65,12 +65,7 @@ class MessageBuffer
void stallMessage(const Address& addr);
// TRUE if head of queue timestamp <= SystemTime
- bool
- isReady() const
- {
- return ((m_prio_heap.size() > 0) &&
- (m_prio_heap.front().m_time <= g_system_ptr->getTime()));
- }
+ bool isReady() const;
void
delayHead()
@@ -145,6 +140,17 @@ class MessageBuffer
void setIncomingLink(int link_id) { m_input_link_id = link_id; }
void setVnet(int net) { m_vnet_id = net; }
+ // Function for figuring out if any of the messages in the buffer can
+ // satisfy the read request for the address in the packet.
+ // Return value, if true, indicates that the request was fulfilled.
+ bool functionalRead(Packet *pkt);
+
+ // Function for figuring out if any of the messages in the buffer need
+ // to be updated with the data from the packet.
+ // Return value indicates the number of messages that were updated.
+ // This required for debugging the code.
+ uint32_t functionalWrite(Packet *pkt);
+
private:
//added by SS
int m_recycle_latency;
diff --git a/src/mem/ruby/buffers/MessageBufferNode.hh b/src/mem/ruby/buffers/MessageBufferNode.hh
index 70afa9831..5e7a52e12 100644
--- a/src/mem/ruby/buffers/MessageBufferNode.hh
+++ b/src/mem/ruby/buffers/MessageBufferNode.hh
@@ -31,7 +31,6 @@
#include <iostream>
-#include "mem/ruby/common/Global.hh"
#include "mem/ruby/slicc_interface/Message.hh"
class MessageBufferNode