summaryrefslogtreecommitdiff
path: root/src/mem
diff options
context:
space:
mode:
authorNathan Binkert <nate@binkert.org>2010-06-10 23:17:06 -0700
committerNathan Binkert <nate@binkert.org>2010-06-10 23:17:06 -0700
commitbc87fa30d72df7db6265be50b2c39dc218076f9f (patch)
tree9e27c5ec1bbdbee048f2e91fc450d71f47bdf88d /src/mem
parentaa7888797032bab49b5f0f637c859740497423d8 (diff)
downloadgem5-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/mem')
-rw-r--r--src/mem/gems_common/Allocator.hh89
-rw-r--r--src/mem/gems_common/RefCnt.hh164
-rw-r--r--src/mem/gems_common/RefCnt_tester.cc78
-rw-r--r--src/mem/gems_common/RefCountable.hh59
-rw-r--r--src/mem/gems_common/SConscript36
-rw-r--r--src/mem/ruby/buffers/MessageBuffer.cc17
-rw-r--r--src/mem/ruby/buffers/MessageBuffer.hh6
-rw-r--r--src/mem/ruby/common/Debug.cc1
-rw-r--r--src/mem/ruby/common/Debug.hh1
-rw-r--r--src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc10
-rw-r--r--src/mem/ruby/network/garnet/fixed-pipeline/RoutingUnit_d.cc4
-rw-r--r--src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc8
-rw-r--r--src/mem/ruby/network/garnet/flexible-pipeline/Router.cc4
-rw-r--r--src/mem/ruby/network/simple/PerfectSwitch.cc8
-rw-r--r--src/mem/ruby/network/simple/Throttle.cc2
-rw-r--r--src/mem/ruby/slicc_interface/Message.hh24
-rw-r--r--src/mem/ruby/slicc_interface/NetworkMessage.hh15
-rw-r--r--src/mem/ruby/system/DMASequencer.cc36
-rw-r--r--src/mem/ruby/system/MemoryControl.cc6
-rw-r--r--src/mem/ruby/system/Sequencer.cc6
-rw-r--r--src/mem/slicc/ast/EnqueueStatementAST.py4
-rw-r--r--src/mem/slicc/symbols/Type.py59
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