# HG changeset patch
# User Brad Beckmann <[email protected]>
# Date 1268941833 25200
# Node ID a6b9c13fe7c9a4d3b4f560df959132b65a3c733a
# Parent  228dffe6662246053d1fbc77dd08c210185420af
Fix bug in Ruby Event queue to avoid multiple wakeups of same consumer in same 
cycle

diff --git a/src/mem/ruby/common/Consumer.hh b/src/mem/ruby/common/Consumer.hh
--- a/src/mem/ruby/common/Consumer.hh
+++ b/src/mem/ruby/common/Consumer.hh
@@ -43,6 +43,9 @@
 
 #include "mem/ruby/common/Global.hh"
 #include "mem/ruby/eventqueue/RubyEventQueue.hh"
+#include <set>
+
+using namespace std;
 
 class MessageBuffer;
 
@@ -61,12 +64,16 @@
   virtual void print(std::ostream& out) const = 0;
   const Time& getLastScheduledWakeup() const { return m_last_scheduled_wakeup; 
}
   void setLastScheduledWakeup(const Time& time) { m_last_scheduled_wakeup = 
time; }
+  bool alreadyScheduled(Time time) { return (m_scheduled_wakeups.find(time) != 
m_scheduled_wakeups.end()); }
+  void insertScheduledWakeupTime(Time time) { 
m_scheduled_wakeups.insert(time); }
+  void removeScheduledWakeupTime(Time time) { assert(alreadyScheduled(time)); 
m_scheduled_wakeups.erase(time); }
 
 private:
   // Private Methods
 
   // Data Members (m_ prefix)
   Time m_last_scheduled_wakeup;
+  std::set<Time> m_scheduled_wakeups;
   Time m_last_wakeup;
 };
 
diff --git a/src/mem/ruby/eventqueue/RubyEventQueue.cc 
b/src/mem/ruby/eventqueue/RubyEventQueue.cc
--- a/src/mem/ruby/eventqueue/RubyEventQueue.cc
+++ b/src/mem/ruby/eventqueue/RubyEventQueue.cc
@@ -56,12 +56,12 @@
 {
   // Check to see if this is a redundant wakeup
   ASSERT(consumer != NULL);
-  if (consumer->getLastScheduledWakeup() != timeAbs) {
+  if (!consumer->alreadyScheduled(timeAbs)) {  
     // This wakeup is not redundant
-    RubyEventQueueNode *thisNode = new RubyEventQueueNode(consumer);
+    RubyEventQueueNode *thisNode = new RubyEventQueueNode(consumer, this);
     assert(timeAbs > getTime());
     schedule(thisNode, (timeAbs * m_clock));
-    consumer->setLastScheduledWakeup(timeAbs * m_clock);
+    consumer->insertScheduledWakeupTime(timeAbs);
   }
 }
 
diff --git a/src/mem/ruby/eventqueue/RubyEventQueueNode.hh 
b/src/mem/ruby/eventqueue/RubyEventQueueNode.hh
--- a/src/mem/ruby/eventqueue/RubyEventQueueNode.hh
+++ b/src/mem/ruby/eventqueue/RubyEventQueueNode.hh
@@ -45,8 +45,8 @@
 class RubyEventQueueNode : public Event {
 public:
   // Constructors
-  RubyEventQueueNode(Consumer* _consumer) 
-    : m_consumer_ptr(_consumer)
+  RubyEventQueueNode(Consumer* _consumer, RubyEventQueue* _eventq) 
+    : m_consumer_ptr(_consumer), m_eventq_ptr(_eventq)
   { 
     setFlags(AutoDelete); 
   }
@@ -56,7 +56,8 @@
 
   // Public Methods
   void print(std::ostream& out) const;
-  virtual void process() { m_consumer_ptr->wakeup(); }
+  virtual void process() { m_consumer_ptr->wakeup(); 
+      m_consumer_ptr->removeScheduledWakeupTime(m_eventq_ptr->getTime()); }
   virtual const char *description() const { return "Ruby Event"; }
 
 private:
@@ -67,6 +68,7 @@
 
   // Data Members (m_ prefix)
   Consumer* m_consumer_ptr;
+  RubyEventQueue* m_eventq_ptr;
 };
 
 // Output operator declaration

_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to