Ruby: use ClockedObject in Consumer class

Many Ruby structures inherit from the Consumer, which is used for scheduling
events. The Consumer used to relay on an Event Manager for scheduling events
and on g_system_ptr for time. With this patch, the Consumer will now use a
ClockedObject to schedule events and to query for current time. This resulted
in several structures being converted from SimObjects to ClockedObjects. Also,
the MessageBuffer class now requires a pointer to a ClockedObject so as to
query for time.
This commit is contained in:
Nilay Vaish
2013-01-14 10:04:21 -06:00
parent cbbc4c7f6b
commit cf232de461
40 changed files with 155 additions and 152 deletions

View File

@@ -47,4 +47,4 @@ void profile_outstanding_persistent_request(int outstanding);
void profile_average_latency_estimate(int latency);
// profile the total message delay of a message across a virtual network
void profileMsgDelay(int virtualNetwork, int delayCycles);
void profileMsgDelay(int virtualNetwork, Time delayCycles);

View File

@@ -36,13 +36,12 @@
//
external_type(MessageBuffer, buffer="yes", inport="yes", outport="yes");
external_type(OutPort, primitive="yes");
structure(InPort, external = "yes", primitive="yes") {
bool isReady();
void dequeue();
int dequeue_getDelayCycles();
Time dequeue_getDelayCycles();
void recycle();
bool isEmpty();
}

View File

@@ -42,6 +42,8 @@ MessageBuffer::MessageBuffer(const string &name)
{
m_msg_counter = 0;
m_consumer_ptr = NULL;
m_clockobj_ptr = NULL;
m_ordering_set = false;
m_strict_fifo = true;
m_size = 0;
@@ -66,10 +68,10 @@ MessageBuffer::MessageBuffer(const string &name)
int
MessageBuffer::getSize()
{
if (m_time_last_time_size_checked == g_system_ptr->getTime()) {
if (m_time_last_time_size_checked == m_clockobj_ptr->curCycle()) {
return m_size_last_time_size_checked;
} else {
m_time_last_time_size_checked = g_system_ptr->getTime();
m_time_last_time_size_checked = m_clockobj_ptr->curCycle();
m_size_last_time_size_checked = m_size;
return m_size;
}
@@ -89,11 +91,11 @@ MessageBuffer::areNSlotsAvailable(int n)
// until next cycle, but enqueue operations effect the visible
// size immediately
int current_size = max(m_size_at_cycle_start, m_size);
if (m_time_last_time_pop < g_system_ptr->getTime()) {
if (m_time_last_time_pop < m_clockobj_ptr->curCycle()) {
// no pops this cycle - m_size is correct
current_size = m_size;
} else {
if (m_time_last_time_enqueue < g_system_ptr->getTime()) {
if (m_time_last_time_enqueue < m_clockobj_ptr->curCycle()) {
// no enqueues this cycle - m_size_at_cycle_start is correct
current_size = m_size_at_cycle_start;
} else {
@@ -155,9 +157,9 @@ MessageBuffer::enqueue(MsgPtr message, Time delta)
m_size++;
// record current time incase we have a pop that also adjusts my size
if (m_time_last_time_enqueue < g_system_ptr->getTime()) {
if (m_time_last_time_enqueue < m_clockobj_ptr->curCycle()) {
m_msgs_this_cycle = 0; // first msg this cycle
m_time_last_time_enqueue = g_system_ptr->getTime();
m_time_last_time_enqueue = m_clockobj_ptr->curCycle();
}
m_msgs_this_cycle++;
@@ -168,7 +170,7 @@ MessageBuffer::enqueue(MsgPtr message, Time delta)
// Calculate the arrival time of the message, that is, the first
// cycle the message can be dequeued.
assert(delta>0);
Time current_time = g_system_ptr->getTime();
Time current_time = m_clockobj_ptr->curCycle();
Time arrival_time = 0;
if (!RubySystem::getRandomization() || (m_randomization == false)) {
// No randomization
@@ -191,11 +193,10 @@ MessageBuffer::enqueue(MsgPtr message, Time delta)
if (arrival_time < m_last_arrival_time) {
panic("FIFO ordering violated: %s name: %s current time: %d "
"delta: %d arrival_time: %d last arrival_time: %d\n",
*this, m_name,
current_time * g_system_ptr->clockPeriod(),
delta * g_system_ptr->clockPeriod(),
arrival_time * g_system_ptr->clockPeriod(),
m_last_arrival_time * g_system_ptr->clockPeriod());
*this, m_name, current_time * m_clockobj_ptr->clockPeriod(),
delta * m_clockobj_ptr->clockPeriod(),
arrival_time * m_clockobj_ptr->clockPeriod(),
m_last_arrival_time * m_clockobj_ptr->clockPeriod());
}
}
@@ -208,10 +209,10 @@ MessageBuffer::enqueue(MsgPtr message, Time delta)
Message* msg_ptr = message.get();
assert(msg_ptr != NULL);
assert(g_system_ptr->getTime() >= msg_ptr->getLastEnqueueTime() &&
assert(m_clockobj_ptr->curCycle() >= msg_ptr->getLastEnqueueTime() &&
"ensure we aren't dequeued early");
msg_ptr->setDelayedCycles(g_system_ptr->getTime() -
msg_ptr->setDelayedCycles(m_clockobj_ptr->curCycle() -
msg_ptr->getLastEnqueueTime() +
msg_ptr->getDelayedCycles());
msg_ptr->setLastEnqueueTime(arrival_time);
@@ -222,9 +223,8 @@ MessageBuffer::enqueue(MsgPtr message, Time delta)
push_heap(m_prio_heap.begin(), m_prio_heap.end(),
greater<MessageBufferNode>());
DPRINTF(RubyQueue, "Enqueue with arrival_time %lld.\n",
arrival_time * g_system_ptr->clockPeriod());
DPRINTF(RubyQueue, "Enqueue Message: %s.\n", (*(message.get())));
DPRINTF(RubyQueue, "Enqueue arrival_time: %lld, Message: %s\n",
arrival_time * m_clockobj_ptr->clockPeriod(), *(message.get()));
// Schedule the wakeup
if (m_consumer_ptr != NULL) {
@@ -235,18 +235,11 @@ MessageBuffer::enqueue(MsgPtr message, Time delta)
}
}
int
Time
MessageBuffer::dequeue_getDelayCycles(MsgPtr& message)
{
int delay_cycles = -1; // null value
dequeue(message);
// get the delay cycles
delay_cycles = setAndReturnDelayCycles(message);
assert(delay_cycles >= 0);
return delay_cycles;
return setAndReturnDelayCycles(message);
}
void
@@ -259,21 +252,17 @@ MessageBuffer::dequeue(MsgPtr& message)
DPRINTF(RubyQueue, "Enqueue message is %s\n", (*(message.get())));
}
int
Time
MessageBuffer::dequeue_getDelayCycles()
{
int delay_cycles = -1; // null value
// get MsgPtr of the message about to be dequeued
MsgPtr message = m_prio_heap.front().m_msgptr;
// get the delay cycles
delay_cycles = setAndReturnDelayCycles(message);
Time delayCycles = setAndReturnDelayCycles(message);
dequeue();
assert(delay_cycles >= 0);
return delay_cycles;
return delayCycles;
}
void
@@ -287,9 +276,9 @@ MessageBuffer::pop()
// record previous size and time so the current buffer size isn't
// adjusted until next cycle
if (m_time_last_time_pop < g_system_ptr->getTime()) {
if (m_time_last_time_pop < m_clockobj_ptr->curCycle()) {
m_size_at_cycle_start = m_size;
m_time_last_time_pop = g_system_ptr->getTime();
m_time_last_time_pop = m_clockobj_ptr->curCycle();
}
m_size--;
}
@@ -315,11 +304,11 @@ MessageBuffer::recycle()
MessageBufferNode node = m_prio_heap.front();
pop_heap(m_prio_heap.begin(), m_prio_heap.end(),
greater<MessageBufferNode>());
node.m_time = g_system_ptr->getTime() + m_recycle_latency;
node.m_time = m_clockobj_ptr->curCycle() + m_recycle_latency;
m_prio_heap.back() = node;
push_heap(m_prio_heap.begin(), m_prio_heap.end(),
greater<MessageBufferNode>());
m_consumer_ptr->scheduleEventAbsolute(g_system_ptr->getTime() +
m_consumer_ptr->scheduleEventAbsolute(m_clockobj_ptr->curCycle() +
m_recycle_latency);
}
@@ -335,7 +324,7 @@ MessageBuffer::reanalyzeMessages(const Address& addr)
//
while(!m_stall_msg_map[addr].empty()) {
m_msg_counter++;
MessageBufferNode msgNode(g_system_ptr->getTime() + 1,
MessageBufferNode msgNode(m_clockobj_ptr->curCycle() + 1,
m_msg_counter,
m_stall_msg_map[addr].front());
@@ -364,7 +353,7 @@ MessageBuffer::reanalyzeAllMessages()
while(!(map_iter->second).empty()) {
m_msg_counter++;
MessageBufferNode msgNode(g_system_ptr->getTime() + 1,
MessageBufferNode msgNode(m_clockobj_ptr->curCycle() + 1,
m_msg_counter,
(map_iter->second).front());
@@ -397,23 +386,19 @@ MessageBuffer::stallMessage(const Address& addr)
(m_stall_msg_map[addr]).push_back(message);
}
int
Time
MessageBuffer::setAndReturnDelayCycles(MsgPtr msg_ptr)
{
int delay_cycles = -1; // null value
// get the delay cycles of the message at the top of the queue
// this function should only be called on dequeue
// ensure the msg hasn't been enqueued
assert(msg_ptr->getLastEnqueueTime() <= g_system_ptr->getTime());
msg_ptr->setDelayedCycles(g_system_ptr->getTime() -
msg_ptr->getLastEnqueueTime() +
msg_ptr->getDelayedCycles());
delay_cycles = msg_ptr->getDelayedCycles();
assert(msg_ptr->getLastEnqueueTime() <= m_clockobj_ptr->curCycle());
msg_ptr->setDelayedCycles(m_clockobj_ptr->curCycle() -
msg_ptr->getLastEnqueueTime() +
msg_ptr->getDelayedCycles());
assert(delay_cycles >= 0);
return delay_cycles;
return msg_ptr->getDelayedCycles();
}
void
@@ -440,7 +425,7 @@ bool
MessageBuffer::isReady() const
{
return ((m_prio_heap.size() > 0) &&
(m_prio_heap.front().m_time <= g_system_ptr->getTime()));
(m_prio_heap.front().m_time <= m_clockobj_ptr->curCycle()));
}
bool

View File

@@ -86,6 +86,12 @@ class MessageBuffer
m_consumer_ptr = consumer_ptr;
}
void setClockObj(ClockedObject* obj)
{
assert(m_clockobj_ptr == NULL);
m_clockobj_ptr = obj;
}
void setDescription(const std::string& name) { m_name = name; }
std::string getDescription() { return m_name;}
@@ -110,12 +116,13 @@ class MessageBuffer
void enqueue(MsgPtr message) { enqueue(message, 1); }
void enqueue(MsgPtr message, Time delta);
// void enqueueAbsolute(const MsgPtr& message, Time absolute_time);
int dequeue_getDelayCycles(MsgPtr& message); // returns delay
// cycles of the
// message
//! returns delay ticks of the message.
Time dequeue_getDelayCycles(MsgPtr& message);
void dequeue(MsgPtr& message);
int dequeue_getDelayCycles(); // returns delay cycles of the message
//! returns delay cycles of the message
Time dequeue_getDelayCycles();
void dequeue() { pop(); }
void pop();
void recycle();
@@ -156,16 +163,19 @@ class MessageBuffer
int m_recycle_latency;
// Private Methods
int setAndReturnDelayCycles(MsgPtr message);
Time setAndReturnDelayCycles(MsgPtr message);
// Private copy constructor and assignment operator
MessageBuffer(const MessageBuffer& obj);
MessageBuffer& operator=(const MessageBuffer& obj);
// Data Members (m_ prefix)
Consumer* m_consumer_ptr; // Consumer to signal a wakeup(), can be NULL
//! Object used for querying time.
ClockedObject* m_clockobj_ptr;
//! Consumer to signal a wakeup(), can be NULL
Consumer* m_consumer_ptr;
std::vector<MessageBufferNode> m_prio_heap;
// use a std::map for the stalled messages as this container is
// sorted and ensures a well-defined iteration order
typedef std::map< Address, std::list<MsgPtr> > StallMsgMapType;

View File

@@ -27,23 +27,21 @@
*/
#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/system/System.hh"
void
Consumer::scheduleEvent(Time timeDelta)
{
scheduleEventAbsolute(timeDelta + g_system_ptr->getTime());
scheduleEventAbsolute(timeDelta + em->curCycle());
}
void
Consumer::scheduleEventAbsolute(Time timeAbs)
{
Tick evt_time = g_system_ptr->clockPeriod() * timeAbs;
Tick evt_time = em->clockPeriod() * timeAbs;
if (!alreadyScheduled(evt_time)) {
// This wakeup is not redundant
ConsumerEvent *evt = new ConsumerEvent(this);
assert(timeAbs > g_system_ptr->getTime());
assert(timeAbs > em->curCycle());
em->schedule(evt, evt_time);
insertScheduledWakeupTime(evt_time);

View File

@@ -39,12 +39,12 @@
#include <set>
#include "mem/ruby/common/TypeDefines.hh"
#include "sim/eventq.hh"
#include "sim/clocked_object.hh"
class Consumer
{
public:
Consumer(EventManager *_em)
Consumer(ClockedObject *_em)
: m_last_scheduled_wakeup(0), m_last_wakeup(0), em(_em)
{
}
@@ -95,7 +95,7 @@ class Consumer
Tick m_last_scheduled_wakeup;
std::set<Tick> m_scheduled_wakeups;
Tick m_last_wakeup;
EventManager *em;
ClockedObject *em;
class ConsumerEvent : public Event
{

View File

@@ -29,7 +29,7 @@
#include "mem/ruby/network/BasicRouter.hh"
BasicRouter::BasicRouter(const Params *p)
: SimObject(p)
: ClockedObject(p)
{
m_id = p->router_id;
}

View File

@@ -34,9 +34,9 @@
#include <vector>
#include "params/BasicRouter.hh"
#include "sim/sim_object.hh"
#include "sim/clocked_object.hh"
class BasicRouter : public SimObject
class BasicRouter : public ClockedObject
{
public:
typedef BasicRouterParams Params;

View File

@@ -28,9 +28,9 @@
# Brad Beckmann
from m5.params import *
from m5.SimObject import SimObject
from ClockedObject import ClockedObject
class BasicRouter(SimObject):
class BasicRouter(ClockedObject):
type = 'BasicRouter'
cxx_header = "mem/ruby/network/BasicRouter.hh"
router_id = Param.Int("ID in relation to other routers")

View File

@@ -37,7 +37,7 @@ uint32_t Network::m_control_msg_size;
uint32_t Network::m_data_msg_size;
Network::Network(const Params *p)
: SimObject(p)
: ClockedObject(p)
{
m_virtual_networks = p->number_of_virtual_networks;
m_topology_ptr = p->topology;

View File

@@ -49,14 +49,14 @@
#include "mem/protocol/MessageSizeType.hh"
#include "mem/ruby/common/TypeDefines.hh"
#include "params/RubyNetwork.hh"
#include "sim/sim_object.hh"
#include "sim/clocked_object.hh"
class NetDest;
class MessageBuffer;
class Throttle;
class Topology;
class Network : public SimObject
class Network : public ClockedObject
{
public:
typedef RubyNetworkParams Params;

View File

@@ -29,6 +29,7 @@
from m5.params import *
from m5.SimObject import SimObject
from ClockedObject import ClockedObject
from BasicLink import BasicLink
class Topology(SimObject):
@@ -42,7 +43,7 @@ class Topology(SimObject):
print_config = Param.Bool(False,
"display topology config in the stats file")
class RubyNetwork(SimObject):
class RubyNetwork(ClockedObject):
type = 'RubyNetwork'
cxx_class = 'Network'
cxx_header = "mem/ruby/network/Network.hh"

View File

@@ -30,10 +30,10 @@
from m5.params import *
from m5.proxy import *
from m5.SimObject import SimObject
from ClockedObject import ClockedObject
from BasicLink import BasicIntLink, BasicExtLink
class NetworkLink_d(SimObject):
class NetworkLink_d(ClockedObject):
type = 'NetworkLink_d'
cxx_header = "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh"
link_id = Param.Int(Parent.link_id, "link id")

View File

@@ -116,6 +116,7 @@ NetworkInterface_d::addNode(vector<MessageBuffer *>& in,
// the protocol injects messages into the NI
inNode_ptr[j]->setConsumer(this);
inNode_ptr[j]->setClockObj(m_net_ptr);
}
}

View File

@@ -32,7 +32,7 @@
#include "mem/ruby/network/garnet/fixed-pipeline/NetworkLink_d.hh"
NetworkLink_d::NetworkLink_d(const Params *p)
: SimObject(p), Consumer(this)
: ClockedObject(p), Consumer(this)
{
m_latency = p->link_latency;
channel_width = p->channel_width;

View File

@@ -39,11 +39,11 @@
#include "mem/ruby/network/garnet/NetworkHeader.hh"
#include "mem/ruby/network/orion/NetworkPower.hh"
#include "params/NetworkLink_d.hh"
#include "sim/sim_object.hh"
#include "sim/clocked_object.hh"
class GarnetNetwork_d;
class NetworkLink_d : public SimObject, public Consumer
class NetworkLink_d : public ClockedObject, public Consumer
{
public:
typedef NetworkLink_dParams Params;

View File

@@ -38,7 +38,7 @@
class FlexibleConsumer : public Consumer
{
public:
FlexibleConsumer(EventManager *em) : Consumer(em) {}
FlexibleConsumer(ClockedObject *em) : Consumer(em) {}
virtual bool isBufferNotFull(int vc, int inport) { return true; }
virtual void grant_vc(int out_port, int vc, Time grant_time) {}
virtual void release_vc(int out_port, int vc, Time release_time) {}

View File

@@ -30,10 +30,10 @@
from m5.params import *
from m5.proxy import *
from m5.SimObject import SimObject
from ClockedObject import ClockedObject
from BasicLink import BasicIntLink, BasicExtLink
class NetworkLink(SimObject):
class NetworkLink(ClockedObject):
type = 'NetworkLink'
cxx_header = "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh"
link_id = Param.Int(Parent.link_id, "link id")

View File

@@ -106,6 +106,7 @@ NetworkInterface::addNode(vector<MessageBuffer*>& in,
// protocol injects messages into the NI
for (int j = 0; j < m_virtual_networks; j++) {
inNode_ptr[j]->setConsumer(this);
inNode_ptr[j]->setClockObj(m_net_ptr);
}
}

View File

@@ -32,7 +32,7 @@
#include "mem/ruby/network/garnet/flexible-pipeline/NetworkLink.hh"
NetworkLink::NetworkLink(const Params *p)
: SimObject(p), FlexibleConsumer(this)
: ClockedObject(p), FlexibleConsumer(this)
{
linkBuffer = new flitBuffer();
m_in_port = 0;

View File

@@ -39,11 +39,11 @@
#include "mem/ruby/network/garnet/flexible-pipeline/flitBuffer.hh"
#include "mem/ruby/network/garnet/NetworkHeader.hh"
#include "params/NetworkLink.hh"
#include "sim/sim_object.hh"
#include "sim/clocked_object.hh"
class GarnetNetwork;
class NetworkLink : public SimObject, public FlexibleConsumer
class NetworkLink : public ClockedObject, public FlexibleConsumer
{
public:
typedef NetworkLinkParams Params;

View File

@@ -68,7 +68,7 @@ PerfectSwitch::init(SimpleNetwork *network_ptr)
}
void
PerfectSwitch::addInPort(const vector<MessageBuffer*>& in)
PerfectSwitch::addInPort(const vector<MessageBuffer*>& in, Switch *sw)
{
assert(in.size() == m_virtual_networks);
NodeID port = m_in.size();
@@ -76,6 +76,8 @@ PerfectSwitch::addInPort(const vector<MessageBuffer*>& in)
for (int j = 0; j < m_virtual_networks; j++) {
m_in[port][j]->setConsumer(this);
m_in[port][j]->setClockObj(sw);
string desc = csprintf("[Queue from port %s %s %s to PerfectSwitch]",
to_string(m_switch_id), to_string(port), to_string(j));
m_in[port][j]->setDescription(desc);

View File

@@ -63,7 +63,7 @@ class PerfectSwitch : public Consumer
{ return csprintf("PerfectSwitch-%i", m_switch_id); }
void init(SimpleNetwork *);
void addInPort(const std::vector<MessageBuffer*>& in);
void addInPort(const std::vector<MessageBuffer*>& in, Switch *);
void addOutPort(const std::vector<MessageBuffer*>& out,
const NetDest& routing_table_entry);
void clearRoutingTables();

View File

@@ -67,7 +67,7 @@ Switch::init()
void
Switch::addInPort(const vector<MessageBuffer*>& in)
{
m_perfect_switch_ptr->addInPort(in);
m_perfect_switch_ptr->addInPort(in, this);
}
void
@@ -97,7 +97,7 @@ Switch::addOutPort(const vector<MessageBuffer*>& out,
m_perfect_switch_ptr->addOutPort(intermediateBuffers, routing_table_entry);
// Hook the queues to the Throttle
throttle_ptr->addLinks(intermediateBuffers, out);
throttle_ptr->addLinks(intermediateBuffers, out, this);
}
void

View File

@@ -50,7 +50,7 @@ static int network_message_to_size(NetworkMessage* net_msg_ptr);
Throttle::Throttle(int sID, NodeID node, int link_latency,
int link_bandwidth_multiplier, int endpoint_bandwidth,
EventManager *em)
ClockedObject *em)
: Consumer(em)
{
init(node, link_latency, link_bandwidth_multiplier, endpoint_bandwidth);
@@ -59,7 +59,7 @@ Throttle::Throttle(int sID, NodeID node, int link_latency,
Throttle::Throttle(NodeID node, int link_latency,
int link_bandwidth_multiplier, int endpoint_bandwidth,
EventManager *em)
ClockedObject *em)
: Consumer(em)
{
init(node, link_latency, link_bandwidth_multiplier, endpoint_bandwidth);
@@ -93,11 +93,11 @@ Throttle::clear()
void
Throttle::addLinks(const std::vector<MessageBuffer*>& in_vec,
const std::vector<MessageBuffer*>& out_vec)
const std::vector<MessageBuffer*>& out_vec, ClockedObject *em)
{
assert(in_vec.size() == out_vec.size());
for (int i=0; i<in_vec.size(); i++) {
addVirtualNetwork(in_vec[i], out_vec[i]);
addVirtualNetwork(in_vec[i], out_vec[i], em);
}
m_message_counters.resize(MessageSizeType_NUM);
@@ -110,7 +110,8 @@ Throttle::addLinks(const std::vector<MessageBuffer*>& in_vec,
}
void
Throttle::addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr)
Throttle::addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr,
ClockedObject *em)
{
m_units_remaining.push_back(0);
m_in.push_back(in_ptr);
@@ -118,6 +119,8 @@ Throttle::addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr)
// Set consumer and description
m_in[m_vnets]->setConsumer(this);
m_in[m_vnets]->setClockObj(em);
string desc = "[Queue to Throttle " + to_string(m_sID) + " " +
to_string(m_node) + "]";
m_in[m_vnets]->setDescription(desc);

View File

@@ -54,16 +54,16 @@ class Throttle : public Consumer
public:
Throttle(int sID, NodeID node, int link_latency,
int link_bandwidth_multiplier, int endpoint_bandwidth,
EventManager *em);
ClockedObject *em);
Throttle(NodeID node, int link_latency, int link_bandwidth_multiplier,
int endpoint_bandwidth, EventManager *em);
int endpoint_bandwidth, ClockedObject *em);
~Throttle() {}
std::string name()
{ return csprintf("Throttle-%i", m_sID); }
void addLinks(const std::vector<MessageBuffer*>& in_vec,
const std::vector<MessageBuffer*>& out_vec);
const std::vector<MessageBuffer*>& out_vec, ClockedObject *em);
void wakeup();
void printStats(std::ostream& out) const;
@@ -90,7 +90,8 @@ class Throttle : public Consumer
private:
void init(NodeID node, int link_latency, int link_bandwidth_multiplier,
int endpoint_bandwidth);
void addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr);
void addVirtualNetwork(MessageBuffer* in_ptr, MessageBuffer* out_ptr,
ClockedObject *em);
void linkUtilized(double ratio) { m_links_utilized += ratio; }
// Private copy constructor and assignment operator

View File

@@ -137,7 +137,7 @@ Profiler::wakeup()
}
//g_system_ptr->getNetwork()->printStats(out);
schedule(m_event, g_system_ptr->clockEdge(Cycles(m_stats_period )));
schedule(m_event, g_system_ptr->clockEdge(Cycles(m_stats_period)));
}
void
@@ -571,7 +571,7 @@ Profiler::profileSharing(const Address& addr, AccessType type,
}
void
Profiler::profileMsgDelay(int virtualNetwork, int delayCycles)
Profiler::profileMsgDelay(uint32_t virtualNetwork, Time delayCycles)
{
assert(virtualNetwork < m_delayedCyclesVCHistograms.size());
m_delayedCyclesHistogram.add(delayCycles);

View File

@@ -152,7 +152,7 @@ class Profiler : public SimObject
void sequencerRequests(int num) { m_sequencer_requests.add(num); }
void profileMsgDelay(int virtualNetwork, int delayCycles);
void profileMsgDelay(uint32_t virtualNetwork, Time delayCycles);
void print(std::ostream& out) const;

View File

@@ -30,7 +30,7 @@
#include "mem/ruby/system/System.hh"
AbstractController::AbstractController(const Params *p)
: SimObject(p), Consumer(this)
: ClockedObject(p), Consumer(this)
{
m_version = p->version;
m_transitions_per_cycle = p->transitions_per_cycle;

View File

@@ -41,12 +41,12 @@
#include "mem/ruby/system/MachineID.hh"
#include "mem/packet.hh"
#include "params/RubyController.hh"
#include "sim/sim_object.hh"
#include "sim/clocked_object.hh"
class MessageBuffer;
class Network;
class AbstractController : public SimObject, public Consumer
class AbstractController : public ClockedObject, public Consumer
{
public:
typedef RubyControllerParams Params;

View File

@@ -28,9 +28,9 @@
# Brad Beckmann
from m5.params import *
from m5.SimObject import SimObject
from ClockedObject import ClockedObject
class RubyController(SimObject):
class RubyController(ClockedObject):
type = 'RubyController'
cxx_class = 'AbstractController'
cxx_header = "mem/ruby/slicc_interface/AbstractController.hh"

View File

@@ -73,12 +73,11 @@ class Message : public RefCounted
virtual bool functionalWrite(Packet *pkt) = 0;
//{ fatal("Write functional access not implemented!"); }
void setDelayedCycles(const int& cycles) { m_DelayedCycles = cycles; }
const int& getDelayedCycles() const {return m_DelayedCycles;}
int& getDelayedCycles() {return m_DelayedCycles;}
void setDelayedCycles(const Time cycles) { m_DelayedCycles = cycles; }
const Time getDelayedCycles() const {return m_DelayedCycles;}
void setLastEnqueueTime(const Time& time) { m_LastEnqueueTime = time; }
const Time& getLastEnqueueTime() const {return m_LastEnqueueTime;}
Time& getLastEnqueueTime() {return m_LastEnqueueTime;}
const Time getLastEnqueueTime() const {return m_LastEnqueueTime;}
const Time& getTime() const { return m_time; }
void setTime(const Time& new_time) { m_time = new_time; }

View File

@@ -66,7 +66,7 @@ profile_sharing(const Address& addr, AccessType type, NodeID requestor,
}
void
profileMsgDelay(int virtualNetwork, int delayCycles)
profileMsgDelay(uint32_t virtualNetwork, Time delayCycles)
{
g_system_ptr->getProfiler()->profileMsgDelay(virtualNetwork, delayCycles);
}
@@ -86,6 +86,3 @@ profileGetS(const Address& datablock, const Address& PC, const Set& owner,
g_system_ptr->getProfiler()->getAddressProfiler()->
profileGetS(datablock, PC, owner, sharers, requestor);
}

View File

@@ -55,7 +55,7 @@ void profile_token_retry(const Address& addr, AccessType type, int count);
void profile_filter_action(int action);
void profile_persistent_prediction(const Address& addr, AccessType type);
void profile_average_latency_estimate(int latency);
void profileMsgDelay(int virtualNetwork, int delayCycles);
void profileMsgDelay(uint32_t virtualNetwork, Time delayCycles);
void profile_multicast_retry(const Address& addr, int count);
void profileGetX(const Address& datablock, const Address& PC, const Set& owner,

View File

@@ -60,6 +60,8 @@ class MemoryControl : public ClockedObject, public Consumer
virtual void setConsumer(Consumer* consumer_ptr) = 0;
virtual Consumer* getConsumer() = 0;
virtual void setClockObj(ClockedObject* consumer_ptr) {}
virtual void setDescription(const std::string& name) = 0;
virtual std::string getDescription() = 0;

View File

@@ -88,7 +88,7 @@ Sequencer::wakeup()
assert(getDrainState() != Drainable::Draining);
// Check for deadlock of any of the requests
Time current_time = g_system_ptr->getTime();
Time current_time = curCycle();
// Check across all outstanding requests
int total_outstanding = 0;
@@ -130,8 +130,7 @@ Sequencer::wakeup()
if (m_outstanding_count > 0) {
// If there are still outstanding requests, keep checking
schedule(deadlockCheckEvent,
g_system_ptr->clockPeriod() * m_deadlock_threshold + curTick());
schedule(deadlockCheckEvent, clockEdge(m_deadlock_threshold));
}
}
@@ -211,8 +210,7 @@ Sequencer::insertRequest(PacketPtr pkt, RubyRequestType request_type)
// See if we should schedule a deadlock check
if (!deadlockCheckEvent.scheduled() &&
getDrainState() != Drainable::Draining) {
schedule(deadlockCheckEvent,
g_system_ptr->clockPeriod() * m_deadlock_threshold + curTick());
schedule(deadlockCheckEvent, clockEdge(m_deadlock_threshold));
}
Address line_addr(pkt->getAddr());
@@ -242,8 +240,7 @@ Sequencer::insertRequest(PacketPtr pkt, RubyRequestType request_type)
m_writeRequestTable.insert(default_entry);
if (r.second) {
RequestTable::iterator i = r.first;
i->second = new SequencerRequest(pkt, request_type,
g_system_ptr->getTime());
i->second = new SequencerRequest(pkt, request_type, curCycle());
m_outstanding_count++;
} else {
// There is an outstanding write request for the cache line
@@ -263,8 +260,7 @@ Sequencer::insertRequest(PacketPtr pkt, RubyRequestType request_type)
if (r.second) {
RequestTable::iterator i = r.first;
i->second = new SequencerRequest(pkt, request_type,
g_system_ptr->getTime());
i->second = new SequencerRequest(pkt, request_type, curCycle());
m_outstanding_count++;
} else {
// There is an outstanding read request for the cache line
@@ -480,8 +476,8 @@ Sequencer::hitCallback(SequencerRequest* srequest,
m_dataCache_ptr->setMRU(request_line_address);
}
assert(g_system_ptr->getTime() >= issued_time);
Time miss_latency = g_system_ptr->getTime() - issued_time;
assert(curCycle() >= issued_time);
Time miss_latency = curCycle() - issued_time;
// Profile the miss latency for all non-zero demand misses
if (miss_latency != 0) {
@@ -489,18 +485,14 @@ Sequencer::hitCallback(SequencerRequest* srequest,
if (mach == GenericMachineType_L1Cache_wCC) {
g_system_ptr->getProfiler()->missLatencyWcc(issued_time,
initialRequestTime,
forwardRequestTime,
firstResponseTime,
g_system_ptr->getTime());
initialRequestTime, forwardRequestTime,
firstResponseTime, curCycle());
}
if (mach == GenericMachineType_Directory) {
g_system_ptr->getProfiler()->missLatencyDir(issued_time,
initialRequestTime,
forwardRequestTime,
firstResponseTime,
g_system_ptr->getTime());
initialRequestTime, forwardRequestTime,
firstResponseTime, curCycle());
}
DPRINTFR(ProtocolTrace, "%15s %3s %10s%20s %6s>%-6s %s %d cycles\n",

View File

@@ -33,6 +33,8 @@
TimerTable::TimerTable()
{
m_consumer_ptr = NULL;
m_clockobj_ptr = NULL;
m_next_valid = false;
m_next_address = Address(0);
m_next_time = 0;
@@ -48,7 +50,7 @@ TimerTable::isReady() const
updateNext();
}
assert(m_next_valid);
return (g_system_ptr->getTime() >= m_next_time);
return (m_clockobj_ptr->curCycle() >= m_next_time);
}
const Address&
@@ -69,7 +71,7 @@ TimerTable::set(const Address& address, Time relative_latency)
assert(address == line_address(address));
assert(relative_latency > 0);
assert(!m_map.count(address));
Time ready_time = g_system_ptr->getTime() + relative_latency;
Time ready_time = m_clockobj_ptr->curCycle() + relative_latency;
m_map[address] = ready_time;
assert(m_consumer_ptr != NULL);
m_consumer_ptr->scheduleEventAbsolute(ready_time);

View File

@@ -49,6 +49,12 @@ class TimerTable
m_consumer_ptr = consumer_ptr;
}
void setClockObj(ClockedObject* obj)
{
assert(m_clockobj_ptr == NULL);
m_clockobj_ptr = obj;
}
void
setDescription(const std::string& name)
{
@@ -78,7 +84,12 @@ class TimerTable
mutable bool m_next_valid;
mutable Time m_next_time; // Only valid if m_next_valid is true
mutable Address m_next_address; // Only valid if m_next_valid is true
Consumer* m_consumer_ptr; // Consumer to signal a wakeup()
//! Object used for querying time.
ClockedObject* m_clockobj_ptr;
//! Consumer to signal a wakeup()
Consumer* m_consumer_ptr;
std::string m_name;
};

View File

@@ -55,6 +55,6 @@ class AST(PairContainer):
code = self.slicc.codeFormatter()
code('''
panic("Runtime Error at ${{self.location}}, Ruby Time: %d, %s.\\n",
g_system_ptr->getTime(), $message);
curCycle(), $message);
''')
return code

View File

@@ -527,6 +527,8 @@ $c_ident::init()
{
MachineType machine_type;
int base;
machine_type = string_to_MachineType("${{var.machine.ident}}");
base = MachineType_base_number(machine_type);
m_machineID.type = MachineType_${ident};
m_machineID.num = m_version;
@@ -592,8 +594,6 @@ $c_ident::init()
assert var.machine is not None
code('''
machine_type = string_to_MachineType("${{var.machine.ident}}");
base = MachineType_base_number(machine_type);
$vid = m_net_ptr->get${network}NetQueue(m_version + base, $ordered, $vnet, "$vnet_type");
''')
@@ -638,15 +638,14 @@ $vid->setDescription("[Version " + to_string(m_version) + ", ${ident}, name=${{v
for prefetcher in self.prefetchers:
code('${{prefetcher.code}}.setController(this);')
# Set the queue consumers
code()
for port in self.in_ports:
# Set the queue consumers
code('${{port.code}}.setConsumer(this);')
# Set the queue descriptions
code()
for port in self.in_ports:
# Set the queue descriptions
code('${{port.code}}.setDescription("[Version " + to_string(m_version) + ", $ident, $port]");')
# Set the clock object
code('${{port.code}}.setClockObj(this);')
# Initialize the transition profiling
code()
@@ -1139,7 +1138,7 @@ ${ident}_Controller::doTransition(${ident}_Event event,
${ident}_State next_state = state;
DPRINTF(RubyGenerated, "%s, Time: %lld, state: %s, event: %s, addr: %s\\n",
*this, g_system_ptr->getTime(), ${ident}_State_to_string(state),
*this, curCycle(), ${ident}_State_to_string(state),
${ident}_Event_to_string(event), addr);
TransitionResult result =
@@ -1312,7 +1311,7 @@ if (!checkResourceAvailable(%s_RequestType_%s, addr)) {
default:
fatal("Invalid transition\\n"
"%s time: %d addr: %s event: %s state: %s\\n",
name(), g_system_ptr->getTime(), addr, event, state);
name(), curCycle(), addr, event, state);
}
return TransitionResult_Valid;
}