ruby: consumer: avoid using receiver side clock

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.
This commit is contained in:
Nilay Vaish
2013-03-22 15:53:26 -05:00
parent 28005a7626
commit 39e9445468
14 changed files with 39 additions and 29 deletions

View 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();
}
}

View File

@@ -31,19 +31,15 @@
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);
}

View 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;

View 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

View 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_) {

View 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()]++;
}

View 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);

View 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

View 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;
}
}

View 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()]++;
}

View 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;
}
}

View 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

View 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

View 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