diff options
author | Nathan Binkert <nate@binkert.org> | 2010-06-10 23:17:06 -0700 |
---|---|---|
committer | Nathan Binkert <nate@binkert.org> | 2010-06-10 23:17:06 -0700 |
commit | bc87fa30d72df7db6265be50b2c39dc218076f9f (patch) | |
tree | 9e27c5ec1bbdbee048f2e91fc450d71f47bdf88d /src | |
parent | aa7888797032bab49b5f0f637c859740497423d8 (diff) | |
download | gem5-bc87fa30d72df7db6265be50b2c39dc218076f9f.tar.xz |
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.
Diffstat (limited to 'src')
22 files changed, 102 insertions, 535 deletions
diff --git a/src/mem/gems_common/Allocator.hh b/src/mem/gems_common/Allocator.hh deleted file mode 100644 index 59c5a4c98..000000000 --- a/src/mem/gems_common/Allocator.hh +++ /dev/null @@ -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 diff --git a/src/mem/gems_common/RefCnt.hh b/src/mem/gems_common/RefCnt.hh deleted file mode 100644 index 75160fc80..000000000 --- a/src/mem/gems_common/RefCnt.hh +++ /dev/null @@ -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 diff --git a/src/mem/gems_common/RefCnt_tester.cc b/src/mem/gems_common/RefCnt_tester.cc deleted file mode 100644 index 58828604a..000000000 --- a/src/mem/gems_common/RefCnt_tester.cc +++ /dev/null @@ -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; -} - - diff --git a/src/mem/gems_common/RefCountable.hh b/src/mem/gems_common/RefCountable.hh deleted file mode 100644 index 32fb924cf..000000000 --- a/src/mem/gems_common/RefCountable.hh +++ /dev/null @@ -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 diff --git a/src/mem/gems_common/SConscript b/src/mem/gems_common/SConscript deleted file mode 100644 index 86d8bb345..000000000 --- a/src/mem/gems_common/SConscript +++ /dev/null @@ -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') diff --git a/src/mem/ruby/buffers/MessageBuffer.cc b/src/mem/ruby/buffers/MessageBuffer.cc index e64e47cad..26d187305 100644 --- a/src/mem/ruby/buffers/MessageBuffer.cc +++ b/src/mem/ruby/buffers/MessageBuffer.cc @@ -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 diff --git a/src/mem/ruby/buffers/MessageBuffer.hh b/src/mem/ruby/buffers/MessageBuffer.hh index 6b567d70d..1da6c15ae 100644 --- a/src/mem/ruby/buffers/MessageBuffer.hh +++ b/src/mem/ruby/buffers/MessageBuffer.hh @@ -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); diff --git a/src/mem/ruby/common/Debug.cc b/src/mem/ruby/common/Debug.cc index 1bf7ae43b..eb6cc5c47 100644 --- a/src/mem/ruby/common/Debug.cc +++ b/src/mem/ruby/common/Debug.cc @@ -65,7 +65,6 @@ DebugComponentData debugComponents[] = {"Store Buffer", 'b' }, {"Cache", 'c' }, {"Predictor", 'p' }, - {"Allocator", 'a' }, {"Memory", 'M' }, }; diff --git a/src/mem/ruby/common/Debug.hh b/src/mem/ruby/common/Debug.hh index a2344e82d..f8c18a0b5 100644 --- a/src/mem/ruby/common/Debug.hh +++ b/src/mem/ruby/common/Debug.hh @@ -62,7 +62,6 @@ enum DebugComponents STOREBUFFER_COMP, CACHE_COMP, PREDICTOR_COMP, - ALLOCATOR_COMP, MEMORY_COMP, NUMBER_OF_COMPS }; diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc index da86c32fa..2a2536d53 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc @@ -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(); diff --git a/src/mem/ruby/network/garnet/fixed-pipeline/RoutingUnit_d.cc b/src/mem/ruby/network/garnet/fixed-pipeline/RoutingUnit_d.cc index 0c215efd3..fabda735a 100644 --- a/src/mem/ruby/network/garnet/fixed-pipeline/RoutingUnit_d.cc +++ b/src/mem/ruby/network/garnet/fixed-pipeline/RoutingUnit_d.cc @@ -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; diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc index 697f954ab..c81f5e4b2 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc +++ b/src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc @@ -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; diff --git a/src/mem/ruby/network/garnet/flexible-pipeline/Router.cc b/src/mem/ruby/network/garnet/flexible-pipeline/Router.cc index 10696f1ad..4cdb9dad8 100644 --- a/src/mem/ruby/network/garnet/flexible-pipeline/Router.cc +++ b/src/mem/ruby/network/garnet/flexible-pipeline/Router.cc @@ -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); diff --git a/src/mem/ruby/network/simple/PerfectSwitch.cc b/src/mem/ruby/network/simple/PerfectSwitch.cc index cf3a5af9c..8e6114ba9 100644 --- a/src/mem/ruby/network/simple/PerfectSwitch.cc +++ b/src/mem/ruby/network/simple/PerfectSwitch.cc @@ -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]; diff --git a/src/mem/ruby/network/simple/Throttle.cc b/src/mem/ruby/network/simple/Throttle.cc index 2d15b1141..5d74afb24 100644 --- a/src/mem/ruby/network/simple/Throttle.cc +++ b/src/mem/ruby/network/simple/Throttle.cc @@ -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); diff --git a/src/mem/ruby/slicc_interface/Message.hh b/src/mem/ruby/slicc_interface/Message.hh index d9df6f131..ff94fdd40 100644 --- a/src/mem/ruby/slicc_interface/Message.hh +++ b/src/mem/ruby/slicc_interface/Message.hh @@ -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; } diff --git a/src/mem/ruby/slicc_interface/NetworkMessage.hh b/src/mem/ruby/slicc_interface/NetworkMessage.hh index 41365ff9e..c92de0937 100644 --- a/src/mem/ruby/slicc_interface/NetworkMessage.hh +++ b/src/mem/ruby/slicc_interface/NetworkMessage.hh @@ -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() { } diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc index 5d9037358..a7f3a8aec 100644 --- a/src/mem/ruby/system/DMASequencer.cc +++ b/src/mem/ruby/system/DMASequencer.cc @@ -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 diff --git a/src/mem/ruby/system/MemoryControl.cc b/src/mem/ruby/system/MemoryControl.cc index 3644a3e59..5c455049e 100644 --- a/src/mem/ruby/system/MemoryControl.cc +++ b/src/mem/ruby/system/MemoryControl.cc @@ -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; diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index dd8cec967..641c8fcb9 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -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()-> diff --git a/src/mem/slicc/ast/EnqueueStatementAST.py b/src/mem/slicc/ast/EnqueueStatementAST.py index faf966460..b27bff629 100644 --- a/src/mem/slicc/ast/EnqueueStatementAST.py +++ b/src/mem/slicc/ast/EnqueueStatementAST.py @@ -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) diff --git a/src/mem/slicc/symbols/Type.py b/src/mem/slicc/symbols/Type.py index c4b4d4275..cefae16ae 100644 --- a/src/mem/slicc/symbols/Type.py +++ b/src/mem/slicc/symbols/Type.py @@ -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 |