base: Move Stats::Info functions to its own source file
[gem5.git] / src / base / statistics.hh
index fbf8ee7698ed26d19afe5208a20604ef3aef1660..20544c2a11a55159c147e6fda80051f54cd7a9ea 100644 (file)
@@ -1,5 +1,18 @@
 /*
+ * Copyright (c) 2019-2020 Arm Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2017, Centre National de la Recherche Scientifique
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -24,8 +37,6 @@
  * 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
  */
 
 /** @file
 #include <iosfwd>
 #include <list>
 #include <map>
+#include <memory>
 #include <string>
 #include <vector>
 
+#include "base/stats/group.hh"
 #include "base/stats/info.hh"
 #include "base/stats/output.hh"
 #include "base/stats/types.hh"
 #include "base/cast.hh"
 #include "base/cprintf.hh"
 #include "base/intmath.hh"
-#include "base/refcnt.hh"
 #include "base/str.hh"
 #include "base/types.hh"
-
-class Callback;
-
-/** The current simulated tick. */
-extern Tick curTick();
+// For curTick().
+#include "sim/core.hh"
 
 /* A namespace for all of the Statistics */
 namespace Stats {
@@ -159,6 +168,8 @@ class Vector2dInfoProxy : public InfoProxy<Stat, Vector2dInfo>
 {
   public:
     Vector2dInfoProxy(Stat &stat) : InfoProxy<Stat, Vector2dInfo>(stat) {}
+
+    Result total() const { return this->s.total(); }
 };
 
 struct StorageParams
@@ -168,9 +179,12 @@ struct StorageParams
 
 class InfoAccess
 {
+  private:
+    Info *_info;
+
   protected:
     /** Set up an info class for this statistic */
-    void setInfo(Info *info);
+    void setInfo(Group *parent, Info *info);
     /** Save Storage class parameters if any */
     void setParams(const StorageParams *params);
     /** Save Storage class parameters if any */
@@ -182,6 +196,9 @@ class InfoAccess
     const Info *info() const;
 
   public:
+    InfoAccess()
+        : _info(nullptr) {};
+
     /**
      * Reset the stat to the default state.
      */
@@ -224,21 +241,27 @@ class DataWrap : public InfoAccess
         return safe_cast<const Info *>(InfoAccess::info());
     }
 
-  protected:
-    /**
-     * Copy constructor, copies are not allowed.
-     */
-    DataWrap(const DataWrap &stat) {}
+  public:
+    DataWrap() = delete;
+    DataWrap(const DataWrap &) = delete;
+    DataWrap &operator=(const DataWrap &) = delete;
 
-    /**
-     * Can't copy stats.
-     */
-    void operator=(const DataWrap &) {}
 
-  public:
-    DataWrap()
+    DataWrap(Group *parent, const char *name, const char *desc)
     {
-        this->setInfo(new Info(self()));
+        auto info = new Info(self());
+        this->setInfo(parent, info);
+
+        if (parent)
+            parent->addStat(info);
+
+        if (name) {
+            info->setName(parent, name);
+            info->flags.set(display);
+        }
+
+        if (desc)
+            info->desc = desc;
     }
 
     /**
@@ -331,13 +354,9 @@ class DataWrapVec : public DataWrap<Derived, InfoProxyType>
   public:
     typedef InfoProxyType<Derived> Info;
 
-    DataWrapVec()
-    {}
-
-    DataWrapVec(const DataWrapVec &ref)
-    {}
-
-    void operator=(const DataWrapVec &)
+    DataWrapVec(Group *parent = nullptr, const char *name = nullptr,
+                const char *desc = nullptr)
+        : DataWrap<Derived, InfoProxyType>(parent, name, desc)
     {}
 
     // The following functions are specific to vectors.  If you use them
@@ -416,6 +435,11 @@ class DataWrapVec2d : public DataWrapVec<Derived, InfoProxyType>
   public:
     typedef InfoProxyType<Derived> Info;
 
+    DataWrapVec2d(Group *parent, const char *name, const char *desc)
+        : DataWrapVec<Derived, InfoProxyType>(parent, name, desc)
+    {
+    }
+
     /**
      * @warning This makes the assumption that if you're gonna subnames a 2d
      * vector, you're subnaming across all y
@@ -632,7 +656,7 @@ class ScalarBase : public DataWrap<Derived, ScalarInfoProxy>
 
   protected:
     /** The storage of this stat. */
-    char storage[sizeof(Storage)] __attribute__ ((aligned (8)));
+    M5_ALIGNED(8) char storage[sizeof(Storage)];
 
   protected:
     /**
@@ -673,7 +697,9 @@ class ScalarBase : public DataWrap<Derived, ScalarInfoProxy>
     Counter value() const { return data()->value(); }
 
   public:
-    ScalarBase()
+    ScalarBase(Group *parent = nullptr, const char *name = nullptr,
+               const char *desc = nullptr)
+        : DataWrap<Derived, ScalarInfoProxy>(parent, name, desc)
     {
         this->doInit();
     }
@@ -741,7 +767,7 @@ class ScalarBase : public DataWrap<Derived, ScalarInfoProxy>
 class ProxyInfo : public ScalarInfo
 {
   public:
-    std::string str() const { return to_string(value()); }
+    std::string str() const { return std::to_string(value()); }
     size_type size() const { return 1; }
     bool check() const { return true; }
     void prepare() { }
@@ -764,7 +790,7 @@ class ValueProxy : public ProxyInfo
     Result total() const { return *scalar; }
 };
 
-template <class T>
+template <class T, class Enabled=void>
 class FunctorProxy : public ProxyInfo
 {
   private:
@@ -777,6 +803,27 @@ class FunctorProxy : public ProxyInfo
     Result total() const { return (*functor)(); }
 };
 
+/**
+ * Template specialization for type std::function<Result()> which holds a copy
+ * of its target instead of a pointer to it. This makes it possible to use a
+ * lambda or other type inline without having to keep track of an instance
+ * somewhere else.
+ */
+template <class T>
+class FunctorProxy<T,
+    typename std::enable_if_t<std::is_constructible<std::function<Result()>,
+        const T &>::value>> : public ProxyInfo
+{
+  private:
+    std::function<Result()> functor;
+
+  public:
+    FunctorProxy(const T &func) : functor(func) {}
+    Counter value() const { return functor(); }
+    Result result() const { return functor(); }
+    Result total() const { return functor(); }
+};
+
 /**
  * A proxy similar to the FunctorProxy, but allows calling a method of a bound
  * object, instead of a global free-standing function.
@@ -803,7 +850,12 @@ class ValueBase : public DataWrap<Derived, ScalarInfoProxy>
     ProxyInfo *proxy;
 
   public:
-    ValueBase() : proxy(NULL) { }
+    ValueBase(Group *parent, const char *name, const char *desc)
+        : DataWrap<Derived, ScalarInfoProxy>(parent, name, desc),
+          proxy(NULL)
+    {
+    }
+
     ~ValueBase() { if (proxy) delete proxy; }
 
     template <class T>
@@ -815,6 +867,15 @@ class ValueBase : public DataWrap<Derived, ScalarInfoProxy>
         return this->self();
     }
 
+    template <class T>
+    Derived &
+    functor(const T &func)
+    {
+        proxy = new FunctorProxy<T>(func);
+        this->setInit();
+        return this->self();
+    }
+
     template <class T>
     Derived &
     functor(T &func)
@@ -1091,8 +1152,9 @@ class VectorBase : public DataWrapVec<Derived, VectorInfoProxy>
     }
 
   public:
-    VectorBase()
-        : storage(NULL)
+    VectorBase(Group *parent, const char *name, const char *desc)
+        : DataWrapVec<Derived, VectorInfoProxy>(parent, name, desc),
+          storage(nullptr), _size(0)
     {}
 
     ~VectorBase()
@@ -1126,7 +1188,7 @@ class VectorBase : public DataWrapVec<Derived, VectorInfoProxy>
     Proxy
     operator[](off_type index)
     {
-        assert (index >= 0 && index < size());
+        assert (index < size());
         return Proxy(this->self(), index);
     }
 };
@@ -1200,7 +1262,7 @@ class VectorProxy
     ScalarProxy<Stat>
     operator[](off_type index)
     {
-        assert (index >= 0 && index < size());
+        assert (index < size());
         return ScalarProxy<Stat>(stat, offset + index);
     }
 
@@ -1231,8 +1293,9 @@ class Vector2dBase : public DataWrapVec2d<Derived, Vector2dInfoProxy>
     const Storage *data(off_type index) const { return &storage[index]; }
 
   public:
-    Vector2dBase()
-        : storage(NULL)
+    Vector2dBase(Group *parent, const char *name, const char *desc)
+        : DataWrapVec2d<Derived, Vector2dInfoProxy>(parent, name, desc),
+          x(0), y(0), _size(0), storage(nullptr)
     {}
 
     ~Vector2dBase()
@@ -1275,7 +1338,7 @@ class Vector2dBase : public DataWrapVec2d<Derived, Vector2dInfoProxy>
     operator[](off_type index)
     {
         off_type offset = index * y;
-        assert (index >= 0 && offset + y <= size());
+        assert (offset + y <= size());
         return Proxy(this->self(), offset, y);
     }
 
@@ -1290,12 +1353,19 @@ class Vector2dBase : public DataWrapVec2d<Derived, Vector2dInfoProxy>
     zero() const
     {
         return data(0)->zero();
-#if 0
+    }
+
+    /**
+     * Return a total of all entries in this vector.
+     * @return The total of all vector entries.
+     */
+    Result
+    total() const
+    {
+        Result total = 0.0;
         for (off_type i = 0; i < size(); ++i)
-            if (!data(i)->zero())
-                return false;
-        return true;
-#endif
+            total += data(i)->result();
+        return total;
     }
 
     void
@@ -1344,7 +1414,7 @@ struct DistParams : public StorageParams
 };
 
 /**
- * Templatized storage and interface for a distrbution stat.
+ * Templatized storage and interface for a distribution stat.
  */
 class DistStor
 {
@@ -1361,7 +1431,8 @@ class DistStor
         /** The number of buckets. Equal to (max-min)/bucket_size. */
         size_type buckets;
 
-        Params() : DistParams(Dist) {}
+        Params() : DistParams(Dist), min(0), max(0), bucket_size(0),
+                   buckets(0) {}
     };
 
   private:
@@ -1505,7 +1576,7 @@ class HistStor
         /** The number of buckets.. */
         size_type buckets;
 
-        Params() : DistParams(Hist) {}
+        Params() : DistParams(Hist), buckets(0) {}
     };
 
   private:
@@ -1567,7 +1638,7 @@ class HistStor
         size_type index =
             (int64_t)std::floor((val - min_bucket) / bucket_size);
 
-        assert(index >= 0 && index < size());
+        assert(index < size());
         cvec[index] += number;
 
         sum += val * number;
@@ -1677,9 +1748,8 @@ class SampleStor
     void
     sample(Counter val, int number)
     {
-        Counter value = val * number;
-        sum += value;
-        squares += value * value;
+        sum += val * number;
+        squares += val * val * number;
         samples += number;
     }
 
@@ -1754,9 +1824,8 @@ class AvgSampleStor
     void
     sample(Counter val, int number)
     {
-        Counter value = val * number;
-        sum += value;
-        squares += value * value;
+        sum += val * number;
+        squares += val * val * number;
     }
 
     /**
@@ -1808,7 +1877,7 @@ class DistBase : public DataWrap<Derived, DistInfoProxy>
 
   protected:
     /** The storage for this stat. */
-    char storage[sizeof(Storage)] __attribute__ ((aligned (8)));
+    M5_ALIGNED(8) char storage[sizeof(Storage)];
 
   protected:
     /**
@@ -1839,7 +1908,10 @@ class DistBase : public DataWrap<Derived, DistInfoProxy>
     }
 
   public:
-    DistBase() { }
+    DistBase(Group *parent, const char *name, const char *desc)
+        : DataWrap<Derived, DistInfoProxy>(parent, name, desc)
+    {
+    }
 
     /**
      * Add a value to the distribtion n times. Calls sample on the storage
@@ -1878,7 +1950,7 @@ class DistBase : public DataWrap<Derived, DistInfoProxy>
     }
 
     /**
-     *  Add the argument distribution to the this distibution.
+     *  Add the argument distribution to the this distribution.
      */
     void add(DistBase &d) { data()->add(d.data()); }
 
@@ -1933,8 +2005,9 @@ class VectorDistBase : public DataWrapVec<Derived, VectorDistInfoProxy>
     }
 
   public:
-    VectorDistBase()
-        : storage(NULL)
+    VectorDistBase(Group *parent, const char *name, const char *desc)
+        : DataWrapVec<Derived, VectorDistInfoProxy>(parent, name, desc),
+          storage(NULL)
     {}
 
     ~VectorDistBase()
@@ -1949,7 +2022,7 @@ class VectorDistBase : public DataWrapVec<Derived, VectorDistInfoProxy>
 
     Proxy operator[](off_type index)
     {
-        assert(index >= 0 && index < size());
+        assert(index < size());
         return Proxy(this->self(), index);
     }
 
@@ -2049,7 +2122,7 @@ class DistProxy
  * Base class for formula statistic node. These nodes are used to build a tree
  * that represents the formula.
  */
-class Node : public RefCounted
+class Node
 {
   public:
     /**
@@ -2072,10 +2145,12 @@ class Node : public RefCounted
      *
      */
     virtual std::string str() const = 0;
+
+    virtual ~Node() {};
 };
 
-/** Reference counting pointer to a function Node. */
-typedef RefCountingPtr<Node> NodePtr;
+/** Shared pointer to a function Node. */
+typedef std::shared_ptr<Node> NodePtr;
 
 class ScalarStatNode : public Node
 {
@@ -2170,7 +2245,7 @@ class ConstNode : public Node
     const VResult &result() const { return vresult; }
     Result total() const { return vresult[0]; };
     size_type size() const { return 1; }
-    std::string str() const { return to_string(vresult[0]); }
+    std::string str() const { return std::to_string(vresult[0]); }
 };
 
 template <class T>
@@ -2200,7 +2275,7 @@ class ConstVectorNode : public Node
         size_type size = this->size();
         std::string tmp = "(";
         for (off_type i = 0; i < size; i++)
-            tmp += csprintf("%s ",to_string(vresult[i]));
+            tmp += csprintf("%s ", std::to_string(vresult[i]));
         tmp += ")";
         return tmp;
     }
@@ -2302,7 +2377,7 @@ class BinaryNode : public Node
     BinaryNode(NodePtr &a, NodePtr &b) : l(a), r(b) {}
 
     const VResult &
-    result() const
+    result() const override
     {
         Op op;
         const VResult &lvec = l->result();
@@ -2334,7 +2409,7 @@ class BinaryNode : public Node
     }
 
     Result
-    total() const
+    total() const override
     {
         const VResult &vec = this->result();
         const VResult &lvec = l->result();
@@ -2366,7 +2441,7 @@ class BinaryNode : public Node
     }
 
     size_type
-    size() const
+    size() const override
     {
         size_type ls = l->size();
         size_type rs = r->size();
@@ -2381,7 +2456,7 @@ class BinaryNode : public Node
     }
 
     std::string
-    str() const
+    str() const override
     {
         return csprintf("(%s %s %s)", l->str(), OpString<Op>::str(), r->str());
     }
@@ -2458,6 +2533,12 @@ class Scalar : public ScalarBase<Scalar, StatStor>
 {
   public:
     using ScalarBase<Scalar, StatStor>::operator=;
+
+    Scalar(Group *parent = nullptr, const char *name = nullptr,
+           const char *desc = nullptr)
+        : ScalarBase<Scalar, StatStor>(parent, name, desc)
+    {
+    }
 };
 
 /**
@@ -2468,10 +2549,22 @@ class Average : public ScalarBase<Average, AvgStor>
 {
   public:
     using ScalarBase<Average, AvgStor>::operator=;
+
+    Average(Group *parent = nullptr, const char *name = nullptr,
+            const char *desc = nullptr)
+        : ScalarBase<Average, AvgStor>(parent, name, desc)
+    {
+    }
 };
 
 class Value : public ValueBase<Value>
 {
+  public:
+    Value(Group *parent = nullptr, const char *name = nullptr,
+          const char *desc = nullptr)
+        : ValueBase<Value>(parent, name, desc)
+    {
+    }
 };
 
 /**
@@ -2480,6 +2573,12 @@ class Value : public ValueBase<Value>
  */
 class Vector : public VectorBase<Vector, StatStor>
 {
+  public:
+    Vector(Group *parent = nullptr, const char *name = nullptr,
+           const char *desc = nullptr)
+        : VectorBase<Vector, StatStor>(parent, name, desc)
+    {
+    }
 };
 
 /**
@@ -2488,6 +2587,12 @@ class Vector : public VectorBase<Vector, StatStor>
  */
 class AverageVector : public VectorBase<AverageVector, AvgStor>
 {
+  public:
+    AverageVector(Group *parent = nullptr, const char *name = nullptr,
+                  const char *desc = nullptr)
+        : VectorBase<AverageVector, AvgStor>(parent, name, desc)
+    {
+    }
 };
 
 /**
@@ -2496,6 +2601,12 @@ class AverageVector : public VectorBase<AverageVector, AvgStor>
  */
 class Vector2d : public Vector2dBase<Vector2d, StatStor>
 {
+  public:
+    Vector2d(Group *parent = nullptr, const char *name = nullptr,
+             const char *desc = nullptr)
+        : Vector2dBase<Vector2d, StatStor>(parent, name, desc)
+    {
+    }
 };
 
 /**
@@ -2505,6 +2616,12 @@ class Vector2d : public Vector2dBase<Vector2d, StatStor>
 class Distribution : public DistBase<Distribution, DistStor>
 {
   public:
+    Distribution(Group *parent = nullptr, const char *name = nullptr,
+                 const char *desc = nullptr)
+        : DistBase<Distribution, DistStor>(parent, name, desc)
+    {
+    }
+
     /**
      * Set the parameters of this distribution. @sa DistStor::Params
      * @param min The minimum value of the distribution.
@@ -2519,6 +2636,9 @@ class Distribution : public DistBase<Distribution, DistStor>
         params->min = min;
         params->max = max;
         params->bucket_size = bkt;
+        // Division by zero is especially serious in an Aarch64 host,
+        // where it gets rounded to allocate 32GiB RAM.
+        assert(bkt > 0);
         params->buckets = (size_type)ceil((max - min + 1.0) / bkt);
         this->setParams(params);
         this->doInit();
@@ -2533,6 +2653,12 @@ class Distribution : public DistBase<Distribution, DistStor>
 class Histogram : public DistBase<Histogram, HistStor>
 {
   public:
+    Histogram(Group *parent = nullptr, const char *name = nullptr,
+              const char *desc = nullptr)
+        : DistBase<Histogram, HistStor>(parent, name, desc)
+    {
+    }
+
     /**
      * Set the parameters of this histogram. @sa HistStor::Params
      * @param size The number of buckets in the histogram
@@ -2559,7 +2685,9 @@ class StandardDeviation : public DistBase<StandardDeviation, SampleStor>
     /**
      * Construct and initialize this distribution.
      */
-    StandardDeviation()
+    StandardDeviation(Group *parent = nullptr, const char *name = nullptr,
+                      const char *desc = nullptr)
+        : DistBase<StandardDeviation, SampleStor>(parent, name, desc)
     {
         SampleStor::Params *params = new SampleStor::Params;
         this->doInit();
@@ -2577,7 +2705,9 @@ class AverageDeviation : public DistBase<AverageDeviation, AvgSampleStor>
     /**
      * Construct and initialize this distribution.
      */
-    AverageDeviation()
+    AverageDeviation(Group *parent = nullptr, const char *name = nullptr,
+                     const char *desc = nullptr)
+        : DistBase<AverageDeviation, AvgSampleStor>(parent, name, desc)
     {
         AvgSampleStor::Params *params = new AvgSampleStor::Params;
         this->doInit();
@@ -2592,6 +2722,12 @@ class AverageDeviation : public DistBase<AverageDeviation, AvgSampleStor>
 class VectorDistribution : public VectorDistBase<VectorDistribution, DistStor>
 {
   public:
+    VectorDistribution(Group *parent = nullptr, const char *name = nullptr,
+                       const char *desc = nullptr)
+        : VectorDistBase<VectorDistribution, DistStor>(parent, name, desc)
+    {
+    }
+
     /**
      * Initialize storage and parameters for this distribution.
      * @param size The size of the vector (the number of distributions).
@@ -2622,6 +2758,13 @@ class VectorStandardDeviation
     : public VectorDistBase<VectorStandardDeviation, SampleStor>
 {
   public:
+    VectorStandardDeviation(Group *parent = nullptr, const char *name = nullptr,
+                            const char *desc = nullptr)
+        : VectorDistBase<VectorStandardDeviation, SampleStor>(parent, name,
+                                                              desc)
+    {
+    }
+
     /**
      * Initialize storage for this distribution.
      * @param size The size of the vector.
@@ -2645,6 +2788,13 @@ class VectorAverageDeviation
     : public VectorDistBase<VectorAverageDeviation, AvgSampleStor>
 {
   public:
+    VectorAverageDeviation(Group *parent = nullptr, const char *name = nullptr,
+                           const char *desc = nullptr)
+        : VectorDistBase<VectorAverageDeviation, AvgSampleStor>(parent, name,
+                                                                desc)
+    {
+    }
+
     /**
      * Initialize storage for this distribution.
      * @param size The size of the vector.
@@ -2736,7 +2886,10 @@ class SparseHistBase : public DataWrap<Derived, SparseHistInfoProxy>
     }
 
   public:
-    SparseHistBase() { }
+    SparseHistBase(Group *parent, const char *name, const char *desc)
+        : DataWrap<Derived, SparseHistInfoProxy>(parent, name, desc)
+    {
+    }
 
     /**
      * Add a value to the distribtion n times. Calls sample on the storage
@@ -2853,6 +3006,12 @@ class SparseHistStor
 class SparseHistogram : public SparseHistBase<SparseHistogram, SparseHistStor>
 {
   public:
+    SparseHistogram(Group *parent = nullptr, const char *name = nullptr,
+                    const char *desc = nullptr)
+        : SparseHistBase<SparseHistogram, SparseHistStor>(parent, name, desc)
+    {
+    }
+
     /**
      * Set the parameters of this histogram. @sa HistStor::Params
      * @param size The number of buckets in the histogram
@@ -2885,21 +3044,25 @@ class Formula : public DataWrapVec<Formula, FormulaInfoProxy>
     /**
      * Create and initialize thie formula, and register it with the database.
      */
-    Formula();
+    Formula(Group *parent = nullptr, const char *name = nullptr,
+            const char *desc = nullptr);
 
-    /**
-     * Create a formula with the given root node, register it with the
-     * database.
-     * @param r The root of the expression tree.
-     */
-    Formula(Temp r);
+    Formula(Group *parent, const char *name, const char *desc,
+            const Temp &r);
 
     /**
      * Set an unitialized Formula to the given root.
      * @param r The root of the expression tree.
      * @return a reference to this formula.
      */
-    const Formula &operator=(Temp r);
+    const Formula &operator=(const Temp &r);
+
+    template<typename T>
+    const Formula &operator=(const T &v)
+    {
+        *this = Temp(v);
+        return *this;
+    }
 
     /**
      * Add the given tree to the existing one.
@@ -2988,7 +3151,9 @@ class Temp
      * Copy the given pointer to this class.
      * @param n A pointer to a Node object to copy.
      */
-    Temp(NodePtr n) : node(n) { }
+    Temp(const NodePtr &n) : node(n) { }
+
+    Temp(NodePtr &&n) : node(std::move(n)) { }
 
     /**
      * Return the node pointer.
@@ -2996,6 +3161,11 @@ class Temp
      */
     operator NodePtr&() { return node; }
 
+    /**
+     * Makde gcc < 4.6.3 happy and explicitly get the underlying node.
+     */
+    NodePtr getNodePtr() const { return node; }
+
   public:
     /**
      * Create a new ScalarStatNode.
@@ -3154,51 +3324,51 @@ class Temp
 inline Temp
 operator+(Temp l, Temp r)
 {
-    return NodePtr(new BinaryNode<std::plus<Result> >(l, r));
+    return Temp(std::make_shared<BinaryNode<std::plus<Result> > >(l, r));
 }
 
 inline Temp
 operator-(Temp l, Temp r)
 {
-    return NodePtr(new BinaryNode<std::minus<Result> >(l, r));
+    return Temp(std::make_shared<BinaryNode<std::minus<Result> > >(l, r));
 }
 
 inline Temp
 operator*(Temp l, Temp r)
 {
-    return NodePtr(new BinaryNode<std::multiplies<Result> >(l, r));
+    return Temp(std::make_shared<BinaryNode<std::multiplies<Result> > >(l, r));
 }
 
 inline Temp
 operator/(Temp l, Temp r)
 {
-    return NodePtr(new BinaryNode<std::divides<Result> >(l, r));
+    return Temp(std::make_shared<BinaryNode<std::divides<Result> > >(l, r));
 }
 
 inline Temp
 operator-(Temp l)
 {
-    return NodePtr(new UnaryNode<std::negate<Result> >(l));
+    return Temp(std::make_shared<UnaryNode<std::negate<Result> > >(l));
 }
 
 template <typename T>
 inline Temp
 constant(T val)
 {
-    return NodePtr(new ConstNode<T>(val));
+    return Temp(std::make_shared<ConstNode<T> >(val));
 }
 
 template <typename T>
 inline Temp
 constantVector(T val)
 {
-    return NodePtr(new ConstVectorNode<T>(val));
+    return Temp(std::make_shared<ConstVectorNode<T> >(val));
 }
 
 inline Temp
 sum(Temp val)
 {
-    return NodePtr(new SumNode<std::plus<Result> >(val));
+    return Temp(std::make_shared<SumNode<std::plus<Result> > >(val));
 }
 
 /** Dump all statistics data to the registered outputs */
@@ -3206,29 +3376,44 @@ void dump();
 void reset();
 void enable();
 bool enabled();
+const Info* resolve(const std::string &name);
+
+/**
+ * Register reset and dump handlers.  These are the functions which
+ * will actually perform the whole statistics reset/dump actions
+ * including processing the reset/dump callbacks
+ */
+typedef void (*Handler)();
+
+void registerHandlers(Handler reset_handler, Handler dump_handler);
 
 /**
  * Register a callback that should be called whenever statistics are
  * reset
  */
-void registerResetCallback(Callback *cb);
+void registerResetCallback(const std::function<void()> &callback);
 
 /**
  * Register a callback that should be called whenever statistics are
  * about to be dumped
  */
-void registerDumpCallback(Callback *cb);
+void registerDumpCallback(const std::function<void()> &callback);
+
+/**
+ * Process all the callbacks in the reset callbacks queue
+ */
+void processResetQueue();
+
+/**
+ * Process all the callbacks in the dump callbacks queue
+ */
+void processDumpQueue();
 
 std::list<Info *> &statsList();
 
 typedef std::map<const void *, Info *> MapType;
 MapType &statsMap();
 
-typedef std::map<std::string, Info *> NameMapType;
-NameMapType &nameMap();
-
-bool validateStatName(const std::string &name);
-
 } // namespace Stats
 
 void debugDumpStats();