ruby: get rid of RefCnt and Allocator stuff use base/refcnt.hh

This was somewhat tricky because the RefCnt API was somewhat odd.  The
biggest confusion was that the the RefCnt object's constructor that
took a TYPE& cloned the object.  I created an explicit virtual clone()
function for things that took advantage of this version of the
constructor.  I was conservative and used clone() when I was in doubt
of whether or not it was necessary.  I still think that there are
probably too many instances of clone(), but hopefully not too many.

I converted several instances of const MsgPtr & to a simple MsgPtr.
If the function wants to avoid the overhead of creating another
reference, then it should just use a regular pointer instead of a ref
counting ptr.

There were a couple of instances where refcounted objects were created
on the stack.  This seems pretty dangerous since if you ever
accidentally make a reference to that object with a ref counting
pointer, bad things are bound to happen.
This commit is contained in:
Nathan Binkert
2010-06-10 23:17:06 -07:00
parent aa78887970
commit bc87fa30d7
22 changed files with 102 additions and 535 deletions

View File

@@ -1,89 +0,0 @@
/*
* Copyright (c) 1999 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ALLOCATOR_H
#define ALLOCATOR_H
#include "mem/gems_common/Vector.hh"
template <class TYPE>
class Allocator {
public:
// Constructors
Allocator() { m_counter = 0; }
// Destructor
~Allocator() { for(int i=0; i<m_pool_vec.size(); i++) { delete m_pool_vec[i]; }}
// Public Methods
TYPE* allocate(const TYPE& obj);
void deallocate(TYPE* obj_ptr);
private:
// Private copy constructor and assignment operator
Allocator(const Allocator& obj);
Allocator& operator=(const Allocator& obj);
// Private Methods
// Data Members (m_ prefix)
Vector<TYPE*> m_pool_vec;
int m_counter;
};
template <class TYPE>
inline
TYPE* Allocator<TYPE>::allocate(const TYPE& obj)
{
m_counter++;
DPRINTF(GemsCommon, "couter %d", m_counter);
TYPE* new_obj_ptr;
// See if we need to allocate any new objects
if (m_pool_vec.size() == 0) {
// Allocate a new item
m_pool_vec.insertAtBottom(new TYPE);
}
// Pop the pointer from the stack/pool
int size = m_pool_vec.size();
new_obj_ptr = m_pool_vec[size-1];
m_pool_vec.setSize(size-1);
// Copy the object
*new_obj_ptr = obj;
return new_obj_ptr;
}
template <class TYPE>
inline
void Allocator<TYPE>::deallocate(TYPE* obj)
{
m_pool_vec.insertAtBottom(obj);
}
#endif //ALLOCATOR_H

View File

@@ -1,164 +0,0 @@
/*
* Copyright (c) 1999-2005 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef REFCNT_H
#define REFCNT_H
#include <iostream>
template <class TYPE>
class RefCnt {
public:
// Constructors
RefCnt();
RefCnt(const TYPE& data);
// Destructor
~RefCnt();
// Public Methods
const TYPE* ref() const { return m_data_ptr; }
TYPE* ref() { return m_data_ptr; }
TYPE* mod_ref() const { return m_data_ptr; }
void freeRef();
void print(std::ostream& out) const;
// Public copy constructor and assignment operator
RefCnt(const RefCnt& obj);
RefCnt& operator=(const RefCnt& obj);
private:
// Private Methods
// Data Members (m_ prefix)
TYPE* m_data_ptr;
// int* m_count_ptr; // Not used yet
};
// Output operator declaration
template <class TYPE>
inline
std::ostream& operator<<(std::ostream& out, const RefCnt<TYPE>& obj);
// ******************* Definitions *******************
// Constructors
template <class TYPE>
inline
RefCnt<TYPE>::RefCnt()
{
m_data_ptr = NULL;
}
template <class TYPE>
inline
RefCnt<TYPE>::RefCnt(const TYPE& data)
{
m_data_ptr = data.clone();
m_data_ptr->setRefCnt(1);
}
template <class TYPE>
inline
RefCnt<TYPE>::~RefCnt()
{
freeRef();
}
template <class TYPE>
inline
void RefCnt<TYPE>::freeRef()
{
if (m_data_ptr != NULL) {
m_data_ptr->decRefCnt();
if (m_data_ptr->getRefCnt() == 0) {
m_data_ptr->destroy();
}
m_data_ptr = NULL;
}
}
template <class TYPE>
inline
void RefCnt<TYPE>::print(std::ostream& out) const
{
if (m_data_ptr == NULL) {
out << "[RefCnt: Null]";
} else {
out << "[RefCnt: ";
m_data_ptr->print(out);
out << "]";
}
}
// Copy constructor
template <class TYPE>
inline
RefCnt<TYPE>::RefCnt(const RefCnt<TYPE>& obj)
{
// m_data_ptr = obj.m_data_ptr->clone();
m_data_ptr = obj.m_data_ptr;
// Increment the reference count
if (m_data_ptr != NULL) {
m_data_ptr->incRefCnt();
}
}
// Assignment operator
template <class TYPE>
inline
RefCnt<TYPE>& RefCnt<TYPE>::operator=(const RefCnt<TYPE>& obj)
{
if (this == &obj) {
// If this is the case, do nothing
// assert(false);
} else {
freeRef();
m_data_ptr = obj.m_data_ptr;
if (m_data_ptr != NULL) {
m_data_ptr->incRefCnt();
}
}
return *this;
}
// Output operator definition
template <class TYPE>
inline
std::ostream& operator<<(std::ostream& out, const RefCnt<TYPE>& obj)
{
obj.print(out);
out << std::flush;
return out;
}
#endif //REFCNT_H

View File

@@ -1,78 +0,0 @@
/*
* Copyright (c) 1999-2005 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Code used to test the RefCnt class
*/
#include "mem/gems_common/RefCnt.hh"
#include "mem/gems_common/RefCountable.hh"
class Foo : public RefCountable {
public:
int m_data;
Foo* clone() const;
private:
};
Foo* Foo::clone() const
{
Foo* temp_ptr;
temp_ptr = new Foo;
*temp_ptr = *this;
cout << "Cloned!" << endl;
return temp_ptr;
}
void bar(RefCnt<Foo> f)
{
cout << f.ref()->m_data << endl;
}
Foo f2;
int main()
{
Foo f;
f.m_data = 2;
{
RefCnt<Foo> a(f);
f.m_data = 3;
cout << a.ref()->m_data << endl;
cout << f.m_data << endl;
f2 = f;
}
bar(f2);
return 0;
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright (c) 1999-2005 Mark D. Hill and David A. Wood
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer;
* redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution;
* neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Virtual base class for things that can be reference counted
*/
#ifndef REFCOUNTABLE_H
#define REFCOUNTABLE_H
#include "mem/gems_common/RefCnt.hh"
class RefCountable {
public:
// Public Methods
RefCountable() { m_refcnt = 0; }
// These are used by the RefCnt class to hold the reference count
// for the object. These really should be private and accessed by a
// friend class, but I can't figure out how to make a template class
// a friend.
void incRefCnt() { m_refcnt++; }
void decRefCnt() { m_refcnt--; }
int getRefCnt() const { return m_refcnt; }
void setRefCnt(int cnt) { m_refcnt = cnt; }
private:
// Private Methods
// Data Members (m_ prefix)
int m_refcnt;
};
#endif //REFCOUNTABLE_H

View File

@@ -1,36 +0,0 @@
# -*- mode:python -*-
# Copyright (c) 2009 The Hewlett-Packard Development Company
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Nathan Binkert
Import('*')
if not env['RUBY']:
Return()
TraceFlag('GemsCommon')

View File

@@ -111,16 +111,12 @@ MessageBuffer::getMsgPtrCopy() const
{
assert(isReady());
MsgPtr temp_msg;
temp_msg = *(m_prio_heap.peekMin().m_msgptr.ref());
assert(temp_msg.ref() != NULL);
return temp_msg;
return m_prio_heap.peekMin().m_msgptr->clone();
}
const Message*
MessageBuffer::peekAtHeadOfQueue() const
{
const Message* msg_ptr;
DEBUG_NEWLINE(QUEUE_COMP, MedPrio);
DEBUG_MSG(QUEUE_COMP, MedPrio,
@@ -128,8 +124,8 @@ MessageBuffer::peekAtHeadOfQueue() const
m_name, g_eventQueue_ptr->getTime()));
assert(isReady());
msg_ptr = m_prio_heap.peekMin().m_msgptr.ref();
assert(msg_ptr != NULL);
const Message* msg_ptr = m_prio_heap.peekMin().m_msgptr.get();
assert(msg_ptr);
DEBUG_EXPR(QUEUE_COMP, MedPrio, *msg_ptr);
DEBUG_NEWLINE(QUEUE_COMP, MedPrio);
@@ -149,7 +145,7 @@ random_time()
}
void
MessageBuffer::enqueue(const MsgPtr& message, Time delta)
MessageBuffer::enqueue(MsgPtr message, Time delta)
{
DEBUG_NEWLINE(QUEUE_COMP, HighPrio);
DEBUG_MSG(QUEUE_COMP, HighPrio,
@@ -214,7 +210,7 @@ MessageBuffer::enqueue(const MsgPtr& message, Time delta)
m_last_arrival_time = arrival_time;
// compute the delay cycles and set enqueue time
Message* msg_ptr = message.mod_ref();
Message* msg_ptr = message.get();
assert(msg_ptr != NULL);
assert(g_eventQueue_ptr->getTime() >= msg_ptr->getLastEnqueueTime() &&
@@ -332,12 +328,11 @@ MessageBuffer::recycle()
}
int
MessageBuffer::setAndReturnDelayCycles(MsgPtr& message)
MessageBuffer::setAndReturnDelayCycles(MsgPtr msg_ptr)
{
int delay_cycles = -1; // null value
// get the delay cycles of the message at the top of the queue
Message* msg_ptr = message.ref();
// this function should only be called on dequeue
// ensure the msg hasn't been enqueued

View File

@@ -102,8 +102,8 @@ class MessageBuffer
return m_prio_heap.peekMin().m_msgptr;
}
void enqueue(const MsgPtr& message) { enqueue(message, 1); }
void enqueue(const MsgPtr& message, Time delta);
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
@@ -136,7 +136,7 @@ class MessageBuffer
int m_recycle_latency;
// Private Methods
int setAndReturnDelayCycles(MsgPtr& message);
int setAndReturnDelayCycles(MsgPtr message);
// Private copy constructor and assignment operator
MessageBuffer(const MessageBuffer& obj);

View File

@@ -65,7 +65,6 @@ DebugComponentData debugComponents[] =
{"Store Buffer", 'b' },
{"Cache", 'c' },
{"Predictor", 'p' },
{"Allocator", 'a' },
{"Memory", 'M' },
};

View File

@@ -62,7 +62,6 @@ enum DebugComponents
STOREBUFFER_COMP,
CACHE_COMP,
PREDICTOR_COMP,
ALLOCATOR_COMP,
MEMORY_COMP,
NUMBER_OF_COMPS
};

View File

@@ -107,7 +107,8 @@ void NetworkInterface_d::addNode(Vector<MessageBuffer*>& in, Vector<MessageBuff
bool NetworkInterface_d::flitisizeMessage(MsgPtr msg_ptr, int vnet)
{
NetworkMessage *net_msg_ptr = dynamic_cast<NetworkMessage*>(msg_ptr.ref());
NetworkMessage *net_msg_ptr =
safe_cast<NetworkMessage *>(msg_ptr.get());
NetDest net_msg_dest = net_msg_ptr->getInternalDestination();
Vector<NodeID> dest_nodes = net_msg_dest.getAllDest(); // gets all the destinations associated with this message.
@@ -120,10 +121,11 @@ bool NetworkInterface_d::flitisizeMessage(MsgPtr msg_ptr, int vnet)
{
return false ;
}
MsgPtr new_msg_ptr = *(msg_ptr.ref());
MsgPtr new_msg_ptr = msg_ptr->clone();
NodeID destID = dest_nodes[ctr];
NetworkMessage *new_net_msg_ptr = dynamic_cast<NetworkMessage*>(new_msg_ptr.ref());
NetworkMessage *new_net_msg_ptr =
safe_cast<NetworkMessage *>(new_msg_ptr.get());
if(dest_nodes.size() > 1)
{
NetDest personal_dest;
@@ -145,7 +147,7 @@ bool NetworkInterface_d::flitisizeMessage(MsgPtr msg_ptr, int vnet)
{
m_net_ptr->increment_injected_flits();
flit_d *fl = new flit_d(i, vc, vnet, num_flits, new_msg_ptr);
fl->set_delay(g_eventQueue_ptr->getTime() - (msg_ptr.ref())->getTime());
fl->set_delay(g_eventQueue_ptr->getTime() - msg_ptr->getTime());
m_ni_buffers[vc]->insert(fl);
}
m_ni_enqueue_time[vc] = g_eventQueue_ptr->getTime();

View File

@@ -61,8 +61,8 @@ void RoutingUnit_d::RC_stage(flit_d *t_flit, InputUnit_d *in_unit, int invc)
int RoutingUnit_d::routeCompute(flit_d *t_flit)
{
MsgPtr msg_ptr = t_flit->get_msg_ptr();
NetworkMessage* net_msg_ptr = NULL;
net_msg_ptr = dynamic_cast<NetworkMessage*>(msg_ptr.ref());
NetworkMessage* net_msg_ptr =
safe_cast<NetworkMessage*>(msg_ptr.get());
NetDest msg_destination = net_msg_ptr->getInternalDestination();
int output_link = -1;

View File

@@ -103,7 +103,8 @@ void NetworkInterface::request_vc(int in_vc, int in_port, NetDest destination, T
bool NetworkInterface::flitisizeMessage(MsgPtr msg_ptr, int vnet)
{
NetworkMessage *net_msg_ptr = dynamic_cast<NetworkMessage*>(msg_ptr.ref());
NetworkMessage *net_msg_ptr =
safe_cast<NetworkMessage*>(msg_ptr.get());
NetDest net_msg_dest = net_msg_ptr->getInternalDestination();
Vector<NodeID> dest_nodes = net_msg_dest.getAllDest(); // gets all the destinations associated with this message.
int num_flits = (int) ceil((double) m_net_ptr->MessageSizeType_to_int(net_msg_ptr->getMessageSize())/m_net_ptr->getFlitSize() ); // Number of flits is dependent on the link bandwidth available. This is expressed in terms of bytes/cycle or the flit size
@@ -117,10 +118,11 @@ bool NetworkInterface::flitisizeMessage(MsgPtr msg_ptr, int vnet)
// did not find a free output vc
return false ;
}
MsgPtr new_msg_ptr = *(msg_ptr.ref());
MsgPtr new_msg_ptr = msg_ptr->clone();
NodeID destID = dest_nodes[ctr];
NetworkMessage *new_net_msg_ptr = dynamic_cast<NetworkMessage*>(new_msg_ptr.ref());
NetworkMessage *new_net_msg_ptr =
safe_cast<NetworkMessage*>(new_msg_ptr.get());
if(dest_nodes.size() > 1)
{
NetDest personal_dest;

View File

@@ -252,7 +252,9 @@ void Router::routeCompute(flit *m_flit, int inport)
g_eventQueue_ptr->scheduleEvent(this, m_net_ptr->getNumPipeStages() -1 );
if((m_flit->get_type() == HEAD_) || (m_flit->get_type() == HEAD_TAIL_))
{
NetDest destination = dynamic_cast<NetworkMessage*>(m_flit->get_msg_ptr().ref())->getInternalDestination();
NetworkMessage *nm =
safe_cast<NetworkMessage*>(m_flit->get_msg_ptr().get());
NetDest destination = nm->getInternalDestination();
if(m_net_ptr->getNumPipeStages() > 1)
{
m_out_vc_state[outport][outvc]->setState(VC_AB_, g_eventQueue_ptr->getTime() + 1);

View File

@@ -170,7 +170,7 @@ PerfectSwitch::wakeup()
// Peek at message
msg_ptr = m_in[incoming][vnet]->peekMsgPtr();
net_msg_ptr = dynamic_cast<NetworkMessage*>(msg_ptr.ref());
net_msg_ptr = safe_cast<NetworkMessage*>(msg_ptr.get());
DEBUG_EXPR(NETWORK_COMP, MedPrio, *net_msg_ptr);
output_links.clear();
@@ -272,7 +272,7 @@ PerfectSwitch::wakeup()
// This magic line creates a private copy of the
// message
unmodified_msg_ptr = *(msg_ptr.ref());
unmodified_msg_ptr = msg_ptr->clone();
}
// Enqueue it - for all outgoing queues
@@ -282,13 +282,13 @@ PerfectSwitch::wakeup()
if (i > 0) {
// create a private copy of the unmodified
// message
msg_ptr = *(unmodified_msg_ptr.ref());
msg_ptr = unmodified_msg_ptr->clone();
}
// Change the internal destination set of the
// message so it knows which destinations this
// link is responsible for.
net_msg_ptr = safe_cast<NetworkMessage*>(msg_ptr.ref());
net_msg_ptr = safe_cast<NetworkMessage*>(msg_ptr.get());
net_msg_ptr->getInternalDestination() =
output_link_destinations[i];

View File

@@ -157,7 +157,7 @@ Throttle::wakeup()
// Find the size of the message we are moving
MsgPtr msg_ptr = m_in[vnet]->peekMsgPtr();
NetworkMessage* net_msg_ptr =
safe_cast<NetworkMessage*>(msg_ptr.ref());
safe_cast<NetworkMessage*>(msg_ptr.get());
m_units_remaining[vnet] +=
network_message_to_size(net_msg_ptr);

View File

@@ -31,29 +31,31 @@
#include <iostream>
#include "mem/gems_common/RefCnt.hh"
#include "mem/gems_common/RefCountable.hh"
#include "base/refcnt.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/eventqueue/RubyEventQueue.hh"
class Message;
typedef RefCnt<Message> MsgPtr;
typedef RefCountingPtr<Message> MsgPtr;
class Message : public RefCountable
class Message : public RefCounted
{
public:
Message()
: RefCountable()
{
m_time = g_eventQueue_ptr->getTime();
m_LastEnqueueTime = g_eventQueue_ptr->getTime();
m_DelayedCycles = 0;
}
: m_time(g_eventQueue_ptr->getTime()),
m_LastEnqueueTime(g_eventQueue_ptr->getTime()),
m_DelayedCycles(0)
{ }
Message(const Message &other)
: m_time(other.m_time),
m_LastEnqueueTime(other.m_LastEnqueueTime),
m_DelayedCycles(other.m_DelayedCycles)
{ }
virtual ~Message() { }
virtual Message* clone() const = 0;
virtual void destroy() = 0;
virtual void print(std::ostream& out) const = 0;
void setDelayedCycles(const int& cycles) { m_DelayedCycles = cycles; }

View File

@@ -31,8 +31,7 @@
#include <iostream>
#include "mem/gems_common/RefCnt.hh"
#include "mem/gems_common/RefCountable.hh"
#include "base/refcnt.hh"
#include "mem/protocol/MessageSizeType.hh"
#include "mem/ruby/common/Global.hh"
#include "mem/ruby/common/NetDest.hh"
@@ -41,16 +40,18 @@
class Address;
class NetworkMessage;
typedef RefCnt<NetworkMessage> NetMsgPtr;
typedef RefCountingPtr<NetworkMessage> NetMsgPtr;
class NetworkMessage : public Message
{
public:
NetworkMessage()
: Message()
{
m_internal_dest_valid = false;
}
: m_internal_dest_valid(false)
{ }
NetworkMessage(const NetworkMessage &other)
: Message(other), m_internal_dest_valid(other.m_internal_dest_valid)
{ }
virtual ~NetworkMessage() { }

View File

@@ -82,22 +82,22 @@ DMASequencer::makeRequest(const RubyRequest &request)
active_request.bytes_issued = 0;
active_request.pkt = request.pkt;
SequencerMsg msg;
msg.getPhysicalAddress() = Address(paddr);
msg.getLineAddress() = line_address(msg.getPhysicalAddress());
msg.getType() = write ? SequencerRequestType_ST : SequencerRequestType_LD;
SequencerMsg *msg = new SequencerMsg;
msg->getPhysicalAddress() = Address(paddr);
msg->getLineAddress() = line_address(msg->getPhysicalAddress());
msg->getType() = write ? SequencerRequestType_ST : SequencerRequestType_LD;
int offset = paddr & m_data_block_mask;
msg.getLen() = (offset + len) <= RubySystem::getBlockSizeBytes() ?
msg->getLen() = (offset + len) <= RubySystem::getBlockSizeBytes() ?
len : RubySystem::getBlockSizeBytes() - offset;
if (write) {
msg.getDataBlk().setData(data, offset, msg.getLen());
msg->getDataBlk().setData(data, offset, msg->getLen());
}
assert(m_mandatory_q_ptr != NULL);
m_mandatory_q_ptr->enqueue(msg);
active_request.bytes_issued += msg.getLen();
active_request.bytes_issued += msg->getLen();
return RequestStatus_Issued;
}
@@ -113,34 +113,34 @@ DMASequencer::issueNext()
return;
}
SequencerMsg msg;
msg.getPhysicalAddress() = Address(active_request.start_paddr +
SequencerMsg *msg = new SequencerMsg;
msg->getPhysicalAddress() = Address(active_request.start_paddr +
active_request.bytes_completed);
assert((msg.getPhysicalAddress().getAddress() & m_data_block_mask) == 0);
msg.getLineAddress() = line_address(msg.getPhysicalAddress());
assert((msg->getPhysicalAddress().getAddress() & m_data_block_mask) == 0);
msg->getLineAddress() = line_address(msg->getPhysicalAddress());
msg.getType() = (active_request.write ? SequencerRequestType_ST :
msg->getType() = (active_request.write ? SequencerRequestType_ST :
SequencerRequestType_LD);
msg.getLen() =
msg->getLen() =
(active_request.len -
active_request.bytes_completed < RubySystem::getBlockSizeBytes() ?
active_request.len - active_request.bytes_completed :
RubySystem::getBlockSizeBytes());
if (active_request.write) {
msg.getDataBlk().
msg->getDataBlk().
setData(&active_request.data[active_request.bytes_completed],
0, msg.getLen());
msg.getType() = SequencerRequestType_ST;
0, msg->getLen());
msg->getType() = SequencerRequestType_ST;
} else {
msg.getType() = SequencerRequestType_LD;
msg->getType() = SequencerRequestType_LD;
}
assert(m_mandatory_q_ptr != NULL);
m_mandatory_q_ptr->enqueue(msg);
active_request.bytes_issued += msg.getLen();
active_request.bytes_issued += msg->getLen();
}
void

View File

@@ -239,7 +239,7 @@ MemoryControl::enqueue(const MsgPtr& message, int latency)
{
Time current_time = g_eventQueue_ptr->getTime();
Time arrival_time = current_time + latency;
const MemoryMsg* memMess = dynamic_cast<const MemoryMsg*>(message.ref());
const MemoryMsg* memMess = safe_cast<const MemoryMsg*>(message.get());
physical_address_t addr = memMess->getAddress().getAddress();
MemoryRequestType type = memMess->getType();
bool is_mem_read = (type == MemoryRequestType_MEMORY_READ);
@@ -285,7 +285,7 @@ const Message*
MemoryControl::peek()
{
MemoryNode node = peekNode();
Message* msg_ptr = node.m_msgptr.ref();
Message* msg_ptr = node.m_msgptr.get();
assert(msg_ptr != NULL);
return msg_ptr;
}
@@ -536,7 +536,7 @@ MemoryControl::issueRequest(int bank)
req.m_msg_counter, req.m_addr, req.m_is_mem_read? 'R':'W',
current_time, bank);
}
if (req.m_msgptr.ref() != NULL) { // don't enqueue L3 writebacks
if (req.m_msgptr) { // don't enqueue L3 writebacks
enqueueToDirectory(req, m_mem_ctl_latency + m_mem_fixed_delay);
}
m_oldRequest[bank] = 0;

View File

@@ -536,9 +536,9 @@ Sequencer::issueRequest(const RubyRequest& request)
Address line_addr(request.paddr);
line_addr.makeLineAddress();
CacheMsg msg(line_addr, Address(request.paddr), ctype,
Address(request.pc), amtype, request.len, PrefetchBit_No,
request.proc_id);
CacheMsg *msg = new CacheMsg(line_addr, Address(request.paddr), ctype,
Address(request.pc), amtype, request.len, PrefetchBit_No,
request.proc_id);
if (Debug::getProtocolTrace()) {
g_system_ptr->getProfiler()->

View File

@@ -48,12 +48,12 @@ class EnqueueStatementAST(StatementAST):
msg_type = self.type_ast.type
# Add new local var to symbol table
v = Var(self.symtab, "out_msg", self.location, msg_type, "out_msg",
v = Var(self.symtab, "out_msg", self.location, msg_type, "*out_msg",
self.pairs)
self.symtab.newSymbol(v)
# Declare message
code("${{msg_type.ident}} out_msg;")
code("${{msg_type.ident}} *out_msg = new ${{msg_type.ident}};")
# The other statements
t = self.statements.generate(code, None)

View File

@@ -205,7 +205,6 @@ class Type(Symbol):
#include <iostream>
#include "mem/ruby/common/Global.hh"
#include "mem/gems_common/Allocator.hh"
''')
for dm in self.data_members.values():
@@ -242,6 +241,26 @@ $klass ${{self.c_ident}}$parent
code.dedent()
code('}')
# ******** Copy constructor ********
if not self.isGlobal:
code('${{self.c_ident}}(const ${{self.c_ident}}&other)')
# Call superclass constructor
if "interface" in self:
code(' : ${{self["interface"]}}(other)')
code('{')
code.indent()
for dm in self.data_members.values():
code('m_${{dm.ident}} = other.m_${{dm.ident}};')
if self.isMessage:
code('proc_id = other.proc_id;')
code.dedent()
code('}')
# ******** Full init constructor ********
if not self.isGlobal:
params = [ 'const %s& local_%s' % (dm.type.c_ident, dm.ident) \
@@ -270,44 +289,18 @@ $klass ${{self.c_ident}}$parent
code.dedent()
code('}')
# create a static factory method
if "interface" in self:
code('''
static ${{self["interface"]}}*
# create a static factory method and a clone member
code('''
static ${{self.c_ident}}*
create()
{
return new ${{self.c_ident}}();
}
''')
# ******** Message member functions ********
# FIXME: those should be moved into slicc file, slicc should
# support more of the c++ class inheritance
if self.isMessage:
code('''
Message *
${{self.c_ident}}*
clone() const
{
checkAllocator();
return s_allocator_ptr->allocate(*this);
}
void
destroy()
{
checkAllocator();
s_allocator_ptr->deallocate(this);
}
static Allocator<${{self.c_ident}}>* s_allocator_ptr;
static void
checkAllocator()
{
if (s_allocator_ptr == NULL) {
s_allocator_ptr = new Allocator<${{self.c_ident}}>;
}
return new ${{self.c_ident}}(*this);
}
''')
@@ -414,8 +407,6 @@ operator<<(std::ostream& out, const ${{self.c_ident}}& obj)
using namespace std;
''')
if self.isMessage:
code('Allocator<${{self.c_ident}}>* ${{self.c_ident}}::s_allocator_ptr = NULL;')
code('''
/** \\brief Print the state of this object */
void