ruby: consumer: avoid using receiver side clock
authorNilay Vaish <nilay@cs.wisc.edu>
Fri, 22 Mar 2013 20:53:26 +0000 (15:53 -0500)
committerNilay Vaish <nilay@cs.wisc.edu>
Fri, 22 Mar 2013 20:53:26 +0000 (15:53 -0500)
A set of patches was recently committed to allow multiple clock domains
in ruby. In those patches, I had inadvertently made an incorrect use of
the clocks. Suppose object A needs to schedule an event on object B. It
was possible that A accesses B's clock to schedule the event. This is not
possible in actual system. Hence, changes are being to the Consumer class
so as to avoid such happenings. Note that in a multi eventq simulation,
this can possibly lead to an incorrect simulation.

There are two functions in the Consumer class that are used for scheduling
events. The first function takes in the relative delay over the current time
as the argument and adds the current time to it for scheduling the event.
The second function takes in the absolute time (in ticks) for scheduling the
event. The first function is now being moved to protected section of the
class so that only objects of the derived classes can use it. All other
objects will have to specify absolute time while scheduling an event
for some consumer.

14 files changed:
src/mem/ruby/buffers/MessageBuffer.cc
src/mem/ruby/common/Consumer.cc
src/mem/ruby/common/Consumer.hh
src/mem/ruby/network/garnet/fixed-pipeline/InputUnit_d.hh
src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc
src/mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.cc
src/mem/ruby/network/garnet/fixed-pipeline/OutputUnit_d.hh
src/mem/ruby/network/garnet/fixed-pipeline/Router_d.cc
src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc
src/mem/ruby/network/garnet/flexible-pipeline/NetworkLink.cc
src/mem/ruby/network/garnet/flexible-pipeline/Router.cc
src/mem/ruby/system/RubyMemoryControl.cc
src/mem/ruby/system/TimerTable.cc
src/mem/ruby/system/WireBuffer.cc

index 92c989851e3c23e693adf445627c55f8635dafcc..e78b99b2b2febf80f8bc9710f69d7ab0a29dc31a 100644 (file)
@@ -231,7 +231,8 @@ MessageBuffer::enqueue(MsgPtr message, Cycles delay)
 
     // Schedule the wakeup
     if (m_consumer_ptr != NULL) {
-        m_consumer_ptr->scheduleEventAbsolute(arrival_time);
+        m_consumer_ptr->scheduleEventAbsolute(
+                arrival_time * m_receiver_ptr->clockPeriod());
         m_consumer_ptr->storeEventInfo(m_vnet_id);
     } else {
         panic("No consumer: %s name: %s\n", *this, m_name);
@@ -312,8 +313,8 @@ MessageBuffer::recycle()
     m_prio_heap.back() = node;
     push_heap(m_prio_heap.begin(), m_prio_heap.end(),
         greater<MessageBufferNode>());
-    m_consumer_ptr->scheduleEventAbsolute(m_receiver_ptr->curCycle() +
-                                          m_recycle_latency);
+    m_consumer_ptr->
+        scheduleEventAbsolute(m_receiver_ptr->clockEdge(m_recycle_latency));
 }
 
 void
@@ -336,7 +337,8 @@ MessageBuffer::reanalyzeMessages(const Address& addr)
         push_heap(m_prio_heap.begin(), m_prio_heap.end(),
                   greater<MessageBufferNode>());
 
-        m_consumer_ptr->scheduleEventAbsolute(msgNode.m_time);
+        m_consumer_ptr->
+            scheduleEventAbsolute(m_receiver_ptr->clockPeriod() * nextCycle);
         m_stall_msg_map[addr].pop_front();
     }
     m_stall_msg_map.erase(addr);
@@ -365,7 +367,8 @@ MessageBuffer::reanalyzeAllMessages()
             push_heap(m_prio_heap.begin(), m_prio_heap.end(),
                       greater<MessageBufferNode>());
 
-            m_consumer_ptr->scheduleEventAbsolute(msgNode.m_time);
+            m_consumer_ptr->
+                scheduleEventAbsolute(m_receiver_ptr->clockPeriod() * nextCycle);
             (map_iter->second).pop_front();
         }
     }
index b7d31ccb07091614cd5d0e639fb33c937638c27e..9f3735709506c9d8cd7b191f03b9bcd5a083e3b0 100644 (file)
 void
 Consumer::scheduleEvent(Cycles timeDelta)
 {
-    timeDelta += em->curCycle();
-    scheduleEventAbsolute(timeDelta);
+    scheduleEventAbsolute(em->clockEdge(timeDelta));
 }
 
 void
-Consumer::scheduleEventAbsolute(Cycles timeAbs)
+Consumer::scheduleEventAbsolute(Tick evt_time)
 {
-    Tick evt_time = em->clockPeriod() * timeAbs;
     if (!alreadyScheduled(evt_time)) {
         // This wakeup is not redundant
         ConsumerEvent *evt = new ConsumerEvent(this);
-        assert(timeAbs > em->curCycle());
-
         em->schedule(evt, evt_time);
         insertScheduledWakeupTime(evt_time);
     }
index c1b4d70b1d1b5cdcf44d533f65612cded5923eaa..57ee69f3e82f255c8358f3b8791d4845badc85f0 100644 (file)
@@ -87,8 +87,10 @@ class Consumer
         m_scheduled_wakeups.erase(time);
     }
 
+    void scheduleEventAbsolute(Tick timeAbs);
+
+  protected:
     void scheduleEvent(Cycles timeDelta);
-    void scheduleEventAbsolute(Cycles timeAbs);
 
   private:
     Tick m_last_scheduled_wakeup;
index c188b12d6920092327f045598174de35a81671a8..6afb4726bd142c68b9248f665c645980c155787c 100644 (file)
@@ -90,7 +90,7 @@ class InputUnit_d : public Consumer
     {
         flit_d *t_flit = new flit_d(in_vc, free_signal, curTime);
         creditQueue->insert(t_flit);
-        m_credit_link->scheduleEvent(Cycles(1));
+        m_credit_link->scheduleEventAbsolute(m_router->clockEdge(Cycles(1)));
     }
 
     inline int
index bdae26fd0c0c5013e1b14e4ac6856780d4ee2106..e49216476147cf0ffdde6e49f646aae4cb1f4a81 100644 (file)
@@ -254,7 +254,8 @@ NetworkInterface_d::wakeup()
         flit_d *credit_flit = new flit_d(t_flit->get_vc(), free_signal,
                                          m_net_ptr->curCycle());
         creditQueue->insert(credit_flit);
-        m_ni_credit_link->scheduleEvent(Cycles(1));
+        m_ni_credit_link->
+            scheduleEventAbsolute(m_net_ptr->clockEdge(Cycles(1)));
 
         int vnet = t_flit->get_vnet();
         m_net_ptr->increment_received_flits(vnet);
@@ -328,7 +329,8 @@ NetworkInterface_d::scheduleOutputLink()
             t_flit->set_time(m_net_ptr->curCycle() + Cycles(1));
             outSrcQueue->insert(t_flit);
             // schedule the out link
-            outNetLink->scheduleEvent(Cycles(1));
+            outNetLink->
+                scheduleEventAbsolute(m_net_ptr->clockEdge(Cycles(1)));
 
             if (t_flit->get_type() == TAIL_ ||
                t_flit->get_type() == HEAD_TAIL_) {
index afa9d63d38e92a1722df689489dfa6ccdaace946..d84bf8e69a24d63c103e720a6dd95a05e7871d14 100644 (file)
@@ -70,7 +70,7 @@ NetworkLink_d::wakeup()
         flit_d *t_flit = link_srcQueue->getTopFlit();
         t_flit->set_time(curCycle() + m_latency);
         linkBuffer->insert(t_flit);
-        link_consumer->scheduleEvent(m_latency);
+        link_consumer->scheduleEventAbsolute(clockEdge(m_latency));
         m_link_utilized++;
         m_vc_load[t_flit->get_vc()]++;
     }
index 50497303c90f4318250a922dfa0c7384d90e4139..48bf361a584df947e08c1bc85491a04afefa2d31 100644 (file)
@@ -84,7 +84,7 @@ class OutputUnit_d : public Consumer
     insert_flit(flit_d *t_flit)
     {
         m_out_buffer->insert(t_flit);
-        m_out_link->scheduleEvent(Cycles(1));
+        m_out_link->scheduleEventAbsolute(m_router->clockEdge(Cycles(1)));
     }
 
     uint32_t functionalWrite(Packet *pkt);
index 44ca8180240cddb92455f240237731f9dac25c74..fd4ce538904a1fe15948d22cd45125b1839bd8f4 100644 (file)
@@ -135,13 +135,13 @@ Router_d::route_req(flit_d *t_flit, InputUnit_d *in_unit, int invc)
 void
 Router_d::vcarb_req()
 {
-    m_vc_alloc->scheduleEvent(Cycles(1));
+    m_vc_alloc->scheduleEventAbsolute(clockEdge(Cycles(1)));
 }
 
 void
 Router_d::swarb_req()
 {
-    m_sw_alloc->scheduleEvent(Cycles(1));
+    m_sw_alloc->scheduleEventAbsolute(clockEdge(Cycles(1)));
 }
 
 void
@@ -154,7 +154,7 @@ void
 Router_d::update_sw_winner(int inport, flit_d *t_flit)
 {
     m_switch->update_sw_winner(inport, t_flit);
-    m_switch->scheduleEvent(Cycles(1));
+    m_switch->scheduleEventAbsolute(clockEdge(Cycles(1)));
 }
 
 void
index 79e295601e2587e8e6d0de8a4bad5825a04a9738..870560af0fa5da1a331fdfcae63b540789286393 100644 (file)
@@ -321,7 +321,8 @@ NetworkInterface::scheduleOutputLink()
                 outSrcQueue->insert(t_flit);
 
                 // schedule the out link
-                outNetLink->scheduleEvent(Cycles(1));
+                outNetLink->
+                    scheduleEventAbsolute(m_net_ptr->clockEdge(Cycles(1)));
                 return;
             }
         }
index cdcd5a6224b52c6ad16d6b41797e2cb4308a5624..9881d806314dbb734114b7801b4f99cb5c4cd5db 100644 (file)
@@ -140,7 +140,8 @@ NetworkLink::wakeup()
     flit *t_flit = link_srcQueue->getTopFlit();
     t_flit->set_time(curCycle() + m_latency);
     linkBuffer->insert(t_flit);
-    link_consumer->scheduleEvent(m_latency);
+    link_consumer->scheduleEventAbsolute(clockEdge(m_latency));
+
     m_link_utilized++;
     m_vc_load[t_flit->get_vc()]++;
 }
index 98317818bc003cb2bb477f4a258ec7c81758b22b..851ababc413f926653ef8098c2ecab741696db38 100644 (file)
@@ -139,7 +139,7 @@ Router::request_vc(int in_vc, int in_port, NetDest destination,
     m_in_vc_state[in_port][in_vc]->setState(VC_AB_, request_time);
     assert(request_time >= curCycle());
     if (request_time > curCycle())
-        m_vc_arbiter->scheduleEventAbsolute(request_time);
+        m_vc_arbiter->scheduleEventAbsolute(clockPeriod() * request_time);
     else
         vc_arbitrate();
 }
@@ -364,7 +364,9 @@ Router::scheduleOutputLinks()
                         m_router_buffers[port][vc_tolookat]->getTopFlit();
                     t_flit->set_time(curCycle() + Cycles(1));
                     m_out_src_queue[port]->insert(t_flit);
-                    m_out_link[port]->scheduleEvent(Cycles(1));
+
+                    m_out_link[port]->
+                        scheduleEventAbsolute(clockEdge(Cycles(1)));
                     break; // done for this port
                 }
             }
@@ -400,7 +402,7 @@ Router::check_arbiter_reschedule()
         for (int vc = 0; vc < m_num_vcs; vc++) {
             if (m_in_vc_state[port][vc]->isInState(VC_AB_, curCycle() +
                                                    Cycles(1))) {
-                m_vc_arbiter->scheduleEvent(Cycles(1));
+                m_vc_arbiter->scheduleEventAbsolute(clockEdge(Cycles(1)));
                 return;
             }
         }
index 78fe6906027357f417c9036c82c1936830bd33fa..75e6e1b06eea9ae86f822465750e21a21b39b6fc 100644 (file)
@@ -384,7 +384,7 @@ RubyMemoryControl::enqueueToDirectory(MemoryNode req, Cycles latency)
             req.m_addr, req.m_is_mem_read ? 'R':'W', arrival_time);
 
     // schedule the wake up
-    m_consumer_ptr->scheduleEventAbsolute(ruby_arrival_time);
+    m_consumer_ptr->scheduleEventAbsolute(arrival_time);
 }
 
 // getBank returns an integer that is unique for each
index d294916113f3710e54bb2472303a3171003943de..38e26e5e9e82ebccf8072c2f69f3afbe16822532 100644 (file)
@@ -75,7 +75,8 @@ TimerTable::set(const Address& address, Cycles relative_latency)
     Cycles ready_time = m_clockobj_ptr->curCycle() + relative_latency;
     m_map[address] = ready_time;
     assert(m_consumer_ptr != NULL);
-    m_consumer_ptr->scheduleEventAbsolute(ready_time);
+    m_consumer_ptr->
+        scheduleEventAbsolute(m_clockobj_ptr->clockPeriod() * ready_time);
     m_next_valid = false;
 
     // Don't always recalculate the next ready address
index e0458550a5c750a0d6436d0af4a9d6100a312150..8c7c9211eec07421f46efe1eb07b03741fe1880f 100644 (file)
@@ -80,7 +80,8 @@ WireBuffer::enqueue(MsgPtr message, Cycles latency)
     MessageBufferNode thisNode(arrival_time, m_msg_counter, message);
     m_message_queue.push_back(thisNode);
     if (m_consumer_ptr != NULL) {
-        m_consumer_ptr->scheduleEventAbsolute(arrival_time);
+        m_consumer_ptr->
+            scheduleEventAbsolute(g_system_ptr->clockPeriod() * arrival_time);
     } else {
         panic("No Consumer for WireBuffer! %s\n", *this);
     }
@@ -128,7 +129,8 @@ WireBuffer::recycle()
     m_message_queue.back() = node;
     push_heap(m_message_queue.begin(), m_message_queue.end(),
         greater<MessageBufferNode>());
-    m_consumer_ptr->scheduleEventAbsolute(node.m_time);
+    m_consumer_ptr->
+        scheduleEventAbsolute(g_system_ptr->clockPeriod() * node.m_time);
 }
 
 bool