diff options
author | Tushar Krishna <tushar@csail.mit.edu> | 2010-03-21 21:22:21 -0700 |
---|---|---|
committer | Tushar Krishna <tushar@csail.mit.edu> | 2010-03-21 21:22:21 -0700 |
commit | 7c20d5511a7c22b360529f2f8452b7d4d5a9785d (patch) | |
tree | 2b70ee38429ab0f95021a29c32a68249486c541a | |
parent | 103f5a2c94bcf84146d8b373890679a2d8816ae7 (diff) | |
download | gem5-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.hh | 34 | ||||
-rw-r--r-- | src/mem/ruby/eventqueue/RubyEventQueue.cc | 6 | ||||
-rw-r--r-- | src/mem/ruby/eventqueue/RubyEventQueueNode.hh | 11 |
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 |