ruby: get rid of RefCnt and Allocator stuff use base/refcnt.hh
authorNathan Binkert <nate@binkert.org>
Fri, 11 Jun 2010 06:17:06 +0000 (23:17 -0700)
committerNathan Binkert <nate@binkert.org>
Fri, 11 Jun 2010 06:17:06 +0000 (23:17 -0700)
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.

22 files changed:
src/mem/gems_common/Allocator.hh [deleted file]
src/mem/gems_common/RefCnt.hh [deleted file]
src/mem/gems_common/RefCnt_tester.cc [deleted file]
src/mem/gems_common/RefCountable.hh [deleted file]
src/mem/gems_common/SConscript [deleted file]
src/mem/ruby/buffers/MessageBuffer.cc
src/mem/ruby/buffers/MessageBuffer.hh
src/mem/ruby/common/Debug.cc
src/mem/ruby/common/Debug.hh
src/mem/ruby/network/garnet/fixed-pipeline/NetworkInterface_d.cc
src/mem/ruby/network/garnet/fixed-pipeline/RoutingUnit_d.cc
src/mem/ruby/network/garnet/flexible-pipeline/NetworkInterface.cc
src/mem/ruby/network/garnet/flexible-pipeline/Router.cc
src/mem/ruby/network/simple/PerfectSwitch.cc
src/mem/ruby/network/simple/Throttle.cc
src/mem/ruby/slicc_interface/Message.hh
src/mem/ruby/slicc_interface/NetworkMessage.hh
src/mem/ruby/system/DMASequencer.cc
src/mem/ruby/system/MemoryControl.cc
src/mem/ruby/system/Sequencer.cc
src/mem/slicc/ast/EnqueueStatementAST.py
src/mem/slicc/symbols/Type.py

diff --git a/src/mem/gems_common/Allocator.hh b/src/mem/gems_common/Allocator.hh
deleted file mode 100644 (file)
index 59c5a4c..0000000
+++ /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 (file)
index 75160fc..0000000
+++ /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 (file)
index 5882860..0000000
+++ /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 (file)
index 32fb924..0000000
+++ /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 (file)
index 86d8bb3..0000000
+++ /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')
index e64e47cadcea91bb3ba48e42a1760466f3a4cc4c..26d1873054358c72c41220c1daea95ac2250f7d2 100644 (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
index 6b567d70d837dadcc4360b2811f7cf5a0a97dffa..1da6c15ae7dfcbdba414c90143e26380e51c28e3 100644 (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);
index 1bf7ae43bdf2543e7a2ac3ba473de8d130efe22e..eb6cc5c47fcb7d3e79036c987db60b03c88c4c36 100644 (file)
@@ -65,7 +65,6 @@ DebugComponentData debugComponents[] =
     {"Store Buffer",      'b' },
     {"Cache",             'c' },
     {"Predictor",         'p' },
-    {"Allocator",         'a' },
     {"Memory",            'M' },
 };
 
index a2344e82d542b1ff137b1878e494397ad425eaed..f8c18a0b5a5464b2abc2d58819bd26e7255673af 100644 (file)
@@ -62,7 +62,6 @@ enum DebugComponents
     STOREBUFFER_COMP,
     CACHE_COMP,
     PREDICTOR_COMP,
-    ALLOCATOR_COMP,
     MEMORY_COMP,
     NUMBER_OF_COMPS
 };
index da86c32fa24a715f5a202d6a54f809599637fd8b..2a2536d53adcb9d2b1e4f1d5f489fcaf773787be 100644 (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();
index 0c215efd38f6c03a0a5238f52bf5a5e677120bba..fabda735aff726d843fafd8d17b58875b818fdb8 100644 (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;
index 697f954ab706df6c64d24292b459331d8da859c8..c81f5e4b239f30bb1db5bf8f382958a2325d3e49 100644 (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;
index 10696f1add0d5c7b9db1117fb189d91837380615..4cdb9dad842b5f0a07667b120305a598f96f08b6 100644 (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);
index cf3a5af9cd268abe731d78ec07be3093bedd3153..8e6114ba956da9eec5e4f50499119e684a1572ed 100644 (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];
 
index 2d15b1141c3bbb68cc5387591cef418a04e50cfd..5d74afb24495079e849a029deb568cd6a6718ead 100644 (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);
 
index d9df6f1310f72e449ef9590ed4bebd986204a814..ff94fdd409e7392ec2c0cba26e6bb4761b90bc09 100644 (file)
 
 #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; }
index 41365ff9ed8d3394c3d295d277904a1fe933d616..c92de09378eb353fbcc0df6232f96f0a70cd53c2 100644 (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"
 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() { }
 
index 5d9037358b2725575dcd440d1716b650ea572856..a7f3a8aec23bb7509d306c1af9f17f0f01671271 100644 (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
index 3644a3e59000bb925b190dbe20a9fcd8e6dd7f5e..5c455049ec28fd252dbc57ea3b3a3fc576a3216b 100644 (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;
index dd8cec96786878a5374ce0b7b67f245f06149ec3..641c8fcb96080abbdec4dd79153f3c9ff5f5b1cf 100644 (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()->
index faf9664602745cd40b0728f402f342966c4b2240..b27bff6290e7ac61acac346f53953b3138b3ea0f 100644 (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)
index c4b4d4275814e4d95ccea30cc9844e5fd311e95c..cefae16aeef799eac24a73fcd26edafc5030f855 100644 (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