summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTushar Krishna <tushar@csail.mit.edu>2010-03-21 21:22:21 -0700
committerTushar Krishna <tushar@csail.mit.edu>2010-03-21 21:22:21 -0700
commit7c20d5511a7c22b360529f2f8452b7d4d5a9785d (patch)
tree2b70ee38429ab0f95021a29c32a68249486c541a
parent103f5a2c94bcf84146d8b373890679a2d8816ae7 (diff)
downloadgem5-7c20d5511a7c22b360529f2f8452b7d4d5a9785d.tar.xz
ruby: Fix multiple wakeups in Ruby Eventqueue
Fix bug in Ruby Event queue to avoid multiple wakeups of same consumer in same cycle
-rw-r--r--src/mem/ruby/common/Consumer.hh34
-rw-r--r--src/mem/ruby/eventqueue/RubyEventQueue.cc6
-rw-r--r--src/mem/ruby/eventqueue/RubyEventQueueNode.hh11
3 files changed, 41 insertions, 10 deletions
diff --git a/src/mem/ruby/common/Consumer.hh b/src/mem/ruby/common/Consumer.hh
index 955c1ffa9..e541ef615 100644
--- a/src/mem/ruby/common/Consumer.hh
+++ b/src/mem/ruby/common/Consumer.hh
@@ -40,6 +40,7 @@
#define CONSUMER_H
#include <iostream>
+#include <set>
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
@@ -55,18 +56,43 @@ public:
virtual ~Consumer() { }
// Public Methods - pure virtual methods
- // void triggerWakeup() { Time time = g_eventQueue_ptr->getTime(); if (m_last_wakeup != time) { wakeup(); m_last_wakeup = time; }}
- void triggerWakeup(RubyEventQueue * eventQueue) { Time time = eventQueue->getTime(); if (m_last_wakeup != time) { wakeup(); m_last_wakeup = time; }}
+ void triggerWakeup(RubyEventQueue * eventQueue)
+ {
+ Time time = eventQueue->getTime();
+ if (m_last_wakeup != time) {
+ wakeup(); m_last_wakeup = time;
+ }
+ }
virtual void wakeup() = 0;
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; }
+ 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
index c497f239a..3cfb52ff1 100644
--- a/src/mem/ruby/eventqueue/RubyEventQueue.cc
+++ b/src/mem/ruby/eventqueue/RubyEventQueue.cc
@@ -56,12 +56,12 @@ void RubyEventQueue::scheduleEventAbsolute(Consumer* consumer, Time timeAbs)
{
// 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
index dc2fc92e7..46d8b317c 100644
--- 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,11 @@ public:
// 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 +71,7 @@ private:
// Data Members (m_ prefix)
Consumer* m_consumer_ptr;
+ RubyEventQueue* m_eventq_ptr;
};
// Output operator declaration