summaryrefslogtreecommitdiff
path: root/src/base
diff options
context:
space:
mode:
Diffstat (limited to 'src/base')
-rw-r--r--src/base/SConscript2
-rw-r--r--src/base/statistics.cc70
-rw-r--r--src/base/statistics.hh204
-rw-r--r--src/base/stats/group.cc129
-rw-r--r--src/base/stats/group.hh175
-rw-r--r--src/base/stats/output.hh16
-rw-r--r--src/base/stats/text.cc53
-rw-r--r--src/base/stats/text.hh41
8 files changed, 617 insertions, 73 deletions
diff --git a/src/base/SConscript b/src/base/SConscript
index 9449a3d4e..96f7b5b50 100644
--- a/src/base/SConscript
+++ b/src/base/SConscript
@@ -81,6 +81,7 @@ Source('loader/object_file.cc')
Source('loader/raw_object.cc')
Source('loader/symtab.cc')
+Source('stats/group.cc')
Source('stats/text.cc')
GTest('addr_range.test', 'addr_range.test.cc')
@@ -101,6 +102,7 @@ DebugFlag('GDBRecv', "Messages received from the remote application")
DebugFlag('GDBSend', "Messages sent to the remote application")
DebugFlag('GDBWrite', "Writes to the remote address space")
DebugFlag('SQL', "SQL queries sent to the server")
+DebugFlag('Stats', "Statistics management")
DebugFlag('StatEvents', "Statistics event tracking")
CompoundFlag('GDBAll',
diff --git a/src/base/statistics.cc b/src/base/statistics.cc
index 123351b80..a186f9763 100644
--- a/src/base/statistics.cc
+++ b/src/base/statistics.cc
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2019 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
* All rights reserved.
*
@@ -67,10 +79,18 @@ statsMap()
}
void
-InfoAccess::setInfo(Info *info)
+InfoAccess::setInfo(Group *parent, Info *info)
{
- if (statsMap().find(this) != statsMap().end())
- panic("shouldn't register stat twice!");
+ panic_if(statsMap().find(this) != statsMap().end() ||
+ _info != nullptr,
+ "shouldn't register stat twice!");
+
+ // New-style stats are reachable through the hierarchy and
+ // shouldn't be added to the global lists.
+ if (parent) {
+ _info = info;
+ return;
+ }
statsList().push_back(info);
@@ -97,17 +117,29 @@ InfoAccess::setInit()
Info *
InfoAccess::info()
{
- MapType::const_iterator i = statsMap().find(this);
- assert(i != statsMap().end());
- return (*i).second;
+ if (_info) {
+ // New-style stats
+ return _info;
+ } else {
+ // Legacy stats
+ MapType::const_iterator i = statsMap().find(this);
+ assert(i != statsMap().end());
+ return (*i).second;
+ }
}
const Info *
InfoAccess::info() const
{
- MapType::const_iterator i = statsMap().find(this);
- assert(i != statsMap().end());
- return (*i).second;
+ if (_info) {
+ // New-style stats
+ return _info;
+ } else {
+ // Legacy stats
+ MapType::const_iterator i = statsMap().find(this);
+ assert(i != statsMap().end());
+ return (*i).second;
+ }
}
StorageParams::~StorageParams()
@@ -224,7 +256,8 @@ Info::baseCheck() const
#endif
panic("Not all stats have been initialized.\n"
"You may need to add <ParentClass>::regStats() to a"
- " new SimObject's regStats() function.");
+ " new SimObject's regStats() function. Name: %s",
+ name);
return false;
}
@@ -376,19 +409,23 @@ HistStor::add(HistStor *hs)
cvec[i] += hs->cvec[i];
}
-Formula::Formula()
+Formula::Formula(Group *parent, const char *name, const char *desc)
+ : DataWrapVec<Formula, FormulaInfoProxy>(parent, name, desc)
+
{
}
-Formula::Formula(Temp r)
+
+
+Formula::Formula(Group *parent, const char *name, const char *desc,
+ const Temp &r)
+ : DataWrapVec<Formula, FormulaInfoProxy>(parent, name, desc)
{
- root = r.getNodePtr();
- setInit();
- assert(size());
+ *this = r;
}
const Formula &
-Formula::operator=(Temp r)
+Formula::operator=(const Temp &r)
{
assert(!root && "Can't change formulas");
root = r.getNodePtr();
@@ -421,6 +458,7 @@ Formula::operator/=(Temp r)
return *this;
}
+
void
Formula::result(VResult &vec) const
{
diff --git a/src/base/statistics.hh b/src/base/statistics.hh
index 6ddf7ff17..f4fa123e9 100644
--- a/src/base/statistics.hh
+++ b/src/base/statistics.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2019 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.
@@ -63,6 +75,7 @@
#include <string>
#include <vector>
+#include "base/stats/group.hh"
#include "base/stats/info.hh"
#include "base/stats/output.hh"
#include "base/stats/types.hh"
@@ -172,9 +185,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 */
@@ -186,6 +202,9 @@ class InfoAccess
const Info *info() const;
public:
+ InfoAccess()
+ : _info(nullptr) {};
+
/**
* Reset the stat to the default state.
*/
@@ -228,21 +247,27 @@ class DataWrap : public InfoAccess
return safe_cast<const Info *>(InfoAccess::info());
}
- protected:
- /**
- * Copy constructor, copies are not allowed.
- */
- DataWrap(const DataWrap &stat) = delete;
+ 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(name);
+ info->flags.set(display);
+ }
+
+ if (desc)
+ info->desc = desc;
}
/**
@@ -335,13 +360,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
@@ -420,6 +441,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
@@ -677,7 +703,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();
}
@@ -807,7 +835,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>
@@ -1095,8 +1128,9 @@ class VectorBase : public DataWrapVec<Derived, VectorInfoProxy>
}
public:
- VectorBase()
- : storage(nullptr), _size(0)
+ VectorBase(Group *parent, const char *name, const char *desc)
+ : DataWrapVec<Derived, VectorInfoProxy>(parent, name, desc),
+ storage(nullptr), _size(0)
{}
~VectorBase()
@@ -1235,8 +1269,9 @@ class Vector2dBase : public DataWrapVec2d<Derived, Vector2dInfoProxy>
const Storage *data(off_type index) const { return &storage[index]; }
public:
- Vector2dBase()
- : x(0), y(0), _size(0), storage(nullptr)
+ Vector2dBase(Group *parent, const char *name, const char *desc)
+ : DataWrapVec2d<Derived, Vector2dInfoProxy>(parent, name, desc),
+ x(0), y(0), _size(0), storage(nullptr)
{}
~Vector2dBase()
@@ -1851,7 +1886,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
@@ -1945,8 +1983,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()
@@ -2472,6 +2511,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)
+ {
+ }
};
/**
@@ -2482,10 +2527,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)
+ {
+ }
};
/**
@@ -2494,6 +2551,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)
+ {
+ }
};
/**
@@ -2502,6 +2565,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)
+ {
+ }
};
/**
@@ -2510,6 +2579,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)
+ {
+ }
};
/**
@@ -2519,6 +2594,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.
@@ -2550,6 +2631,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
@@ -2576,7 +2663,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();
@@ -2594,7 +2683,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();
@@ -2609,6 +2700,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).
@@ -2639,6 +2736,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.
@@ -2662,6 +2766,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.
@@ -2753,7 +2864,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
@@ -2870,6 +2984,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
@@ -2902,21 +3022,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.
diff --git a/src/base/stats/group.cc b/src/base/stats/group.cc
new file mode 100644
index 000000000..2bfc89d00
--- /dev/null
+++ b/src/base/stats/group.cc
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2019 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.
+ *
+ * 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: Andreas Sandberg
+ */
+
+#include "base/stats/group.hh"
+
+#include <cassert>
+
+#include "base/stats/info.hh"
+#include "base/trace.hh"
+#include "debug/Stats.hh"
+#include "sim/sim_object.hh"
+
+namespace Stats {
+
+Group::Group(Group *parent, const char *name)
+ : mergedParent(name ? nullptr : parent)
+{
+ if (parent && name) {
+ parent->addStatGroup(name, this);
+ } else if (parent && !name) {
+ parent->mergeStatGroup(this);
+ }
+}
+
+Group::~Group()
+{
+}
+
+void
+Group::regStats()
+{
+ for (auto &g : mergedStatGroups)
+ g->regStats();
+
+ for (auto &g : statGroups) {
+ if (DTRACE(Stats)) {
+ const SimObject *so = dynamic_cast<const SimObject *>(this);
+ DPRINTF(Stats, "%s: regStats in group %s\n",
+ so ? so->name() : "?",
+ g.first);
+ }
+ g.second->regStats();
+ }
+}
+
+void
+Group::resetStats()
+{
+ for (auto &s : stats)
+ s->reset();
+
+ for (auto &g : mergedStatGroups)
+ g->resetStats();
+
+ for (auto &g : statGroups)
+ g.second->resetStats();
+}
+
+void
+Group::addStat(Stats::Info *info)
+{
+ stats.push_back(info);
+ if (mergedParent)
+ mergedParent->addStat(info);
+}
+
+void
+Group::addStatGroup(const char *name, Group *block)
+{
+ assert(statGroups.find(name) == statGroups.end());
+
+ statGroups[name] = block;
+}
+
+void
+Group::mergeStatGroup(Group *block)
+{
+ mergedStatGroups.push_back(block);
+}
+
+const std::map<std::string, Group *> &
+Group::getStatGroups() const
+{
+ return statGroups;
+}
+
+const std::vector<Info *> &
+Group::getStats() const
+{
+ return stats;
+}
+
+} // namespace Stats
diff --git a/src/base/stats/group.hh b/src/base/stats/group.hh
new file mode 100644
index 000000000..f65e46448
--- /dev/null
+++ b/src/base/stats/group.hh
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2019 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.
+ *
+ * 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: Andreas Sandberg
+ */
+
+#ifndef __BASE_STATS_GROUP_HH__
+#define __BASE_STATS_GROUP_HH__
+
+#include <map>
+#include <vector>
+#include <string>
+
+/**
+ * Convenience macro to add a stat to a statistics group.
+ *
+ * This macro is used to add a stat to a Stats::Group in the
+ * initilization list in the Group's constructor. The macro
+ * automatically assigns the stat to the current group and gives it
+ * the same name as in the class. For example:
+ *
+ * \code
+ * struct MyStats : public Stats::Group
+ * {
+ * Stats::Scalar scalar0;
+ * Stats::Scalar scalar1;
+ *
+ * Group()
+ * : ADD_STAT(scalar0, "Description of scalar0"),
+ * scalar1(this, "scalar1", "Description of scalar1")
+ * {
+ * }
+ * };
+ * \endcode
+ */
+#define ADD_STAT(n, ...) n(this, # n, __VA_ARGS__)
+
+namespace Stats {
+
+class Info;
+
+/**
+ * Statistics container.
+ *
+ * A stat group is a hierarchical structure that contain statistics
+ * and other groups. Groups are used by the stat system to reflect
+ * gem5's SimObject hierarchy and to expose internal hierarchy within
+ * an object. They can also be used to conveniently group stats into
+ * their own class/struct and then be merged into the parent group
+ * (typically a SimObject).
+ */
+class Group
+{
+ public:
+ Group() = delete;
+ Group(const Group &) = delete;
+ Group &operator=(const Group &) = delete;
+
+ /**
+ * Construct a new statistics group.
+ *
+ * The constructor takes two parameters, a parent and a name. The
+ * parent group should typically be specified. However, there are
+ * special cases where the parent group may be null. One such
+ * special case is SimObjects where the Python code performs late
+ * binding of the group parent.
+ *
+ * If the name parameter is NULL, the group gets merged into the
+ * parent group instead of creating a sub-group. Stats belonging
+ * to a merged group behave as if they have been added directly to
+ * the parent group.
+ *
+ * @param parent Parent group to associate this object to.
+ * @param name Name of this group, can be NULL to merge this group
+ * with the parent group.
+ */
+ Group(Group *parent, const char *name = nullptr);
+
+ virtual ~Group();
+
+ /**
+ * Callback to set stat parameters.
+ *
+ * This callback is typically used for complex stats (e.g.,
+ * distributions) that need parameters in addition to a name and a
+ * description. Stat names and descriptions should typically be
+ * set from the constructor usingo from the constructor using the
+ * ADD_STAT macro.
+ */
+ virtual void regStats();
+
+ /**
+ * Callback to reset stats.
+ */
+ virtual void resetStats();
+
+ /**
+ * Register a stat with this group. This method is normally called
+ * automatically when a stat is instantiated.
+ */
+ void addStat(Stats::Info *info);
+
+ /**
+ * Get all child groups associated with this object.
+ */
+ const std::map<std::string, Group *> &getStatGroups() const;
+
+ /**
+ * Get all stats associated with this object.
+ */
+ const std::vector<Info *> &getStats() const;
+
+ /**
+ * Add a stat block as a child of this block
+ *
+ * This method may only be called from a Group constructor or from
+ * regStats. It's typically only called explicitly from Python
+ * when setting up the SimObject hierarchy.
+ */
+ void addStatGroup(const char *name, Group *block);
+
+ private:
+ /**
+ * Merge the contents (stats & children) of a block to this block.
+ *
+ * This is called on a parent group by the child when it is being
+ * merged into the parent.
+ */
+ void mergeStatGroup(Group *block);
+
+ private:
+ /** Parent pointer if merged into parent */
+ Group *const mergedParent;
+
+ std::map<std::string, Group *> statGroups;
+ std::vector<Group *> mergedStatGroups;
+ std::vector<Info *> stats;
+};
+
+} // namespace Stats
+
+#endif // __BASE_STATS_GROUP_HH__
diff --git a/src/base/stats/output.hh b/src/base/stats/output.hh
index 9cd33a5f9..fe3860dfb 100644
--- a/src/base/stats/output.hh
+++ b/src/base/stats/output.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2019 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) 2004-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -48,10 +60,14 @@ class SparseHistInfo; // Sparse histogram
struct Output
{
virtual ~Output() {}
+
virtual void begin() = 0;
virtual void end() = 0;
virtual bool valid() const = 0;
+ virtual void beginGroup(const char *name) = 0;
+ virtual void endGroup() = 0;
+
virtual void visit(const ScalarInfo &info) = 0;
virtual void visit(const VectorInfo &info) = 0;
virtual void visit(const DistInfo &info) = 0;
diff --git a/src/base/stats/text.cc b/src/base/stats/text.cc
index 10e94a770..da68188bd 100644
--- a/src/base/stats/text.cc
+++ b/src/base/stats/text.cc
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2019 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) 2004-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -153,6 +165,32 @@ Text::end()
stream->flush();
}
+std::string
+Text::statName(const std::string &name) const
+{
+ if (path.empty())
+ return name;
+ else
+ return csprintf("%s.%s", path.top(), name);
+}
+
+void
+Text::beginGroup(const char *name)
+{
+ if (path.empty()) {
+ path.push(name);
+ } else {
+ path.push(csprintf("%s.%s", path.top(), name));
+ }
+}
+
+void
+Text::endGroup()
+{
+ assert(!path.empty());
+ path.pop();
+}
+
bool
Text::noOutput(const Info &info)
{
@@ -368,7 +406,7 @@ DistPrint::DistPrint(const Text *text, const VectorDistInfo &info, int i)
void
DistPrint::init(const Text *text, const Info &info)
{
- name = info.name;
+ name = text->statName(info.name);
separatorString = info.separatorString;
desc = info.desc;
flags = info.flags;
@@ -511,7 +549,7 @@ Text::visit(const ScalarInfo &info)
ScalarPrint print;
print.value = info.result();
- print.name = info.name;
+ print.name = statName(info.name);
print.desc = info.desc;
print.flags = info.flags;
print.descriptions = descriptions;
@@ -531,7 +569,7 @@ Text::visit(const VectorInfo &info)
size_type size = info.size();
VectorPrint print;
- print.name = info.name;
+ print.name = statName(info.name);
print.separatorString = info.separatorString;
print.desc = info.desc;
print.flags = info.flags;
@@ -606,8 +644,9 @@ Text::visit(const Vector2dInfo &info)
total += yvec[j];
}
- print.name = info.name + "_" +
- (havesub ? info.subnames[i] : std::to_string(i));
+ print.name = statName(
+ info.name + "_" +
+ (havesub ? info.subnames[i] : std::to_string(i)));
print.desc = info.desc;
print.vec = yvec;
print.total = total;
@@ -619,7 +658,7 @@ Text::visit(const Vector2dInfo &info)
total_subname.push_back("total");
if (info.flags.isSet(::Stats::total) && (info.x > 1)) {
- print.name = info.name;
+ print.name = statName(info.name);
print.subnames = total_subname;
print.desc = info.desc;
print.vec = VResult(1, info.total());
@@ -687,7 +726,7 @@ SparseHistPrint::SparseHistPrint(const Text *text, const SparseHistInfo &info)
void
SparseHistPrint::init(const Text *text, const Info &info)
{
- name = info.name;
+ name = text->statName(info.name);
separatorString = info.separatorString;
desc = info.desc;
flags = info.flags;
diff --git a/src/base/stats/text.hh b/src/base/stats/text.hh
index 8bb290a99..c8fba5a19 100644
--- a/src/base/stats/text.hh
+++ b/src/base/stats/text.hh
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2019 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) 2004-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -32,6 +44,7 @@
#define __BASE_STATS_TEXT_HH__
#include <iosfwd>
+#include <stack>
#include <string>
#include "base/stats/output.hh"
@@ -46,6 +59,9 @@ class Text : public Output
bool mystream;
std::ostream *stream;
+ // Object/group path
+ std::stack<std::string> path;
+
protected:
bool noOutput(const Info &info);
@@ -60,20 +76,25 @@ class Text : public Output
void open(std::ostream &stream);
void open(const std::string &file);
+ std::string statName(const std::string &name) const;
// Implement Visit
- virtual void visit(const ScalarInfo &info);
- virtual void visit(const VectorInfo &info);
- virtual void visit(const DistInfo &info);
- virtual void visit(const VectorDistInfo &info);
- virtual void visit(const Vector2dInfo &info);
- virtual void visit(const FormulaInfo &info);
- virtual void visit(const SparseHistInfo &info);
+ void visit(const ScalarInfo &info) override;
+ void visit(const VectorInfo &info) override;
+ void visit(const DistInfo &info) override;
+ void visit(const VectorDistInfo &info) override;
+ void visit(const Vector2dInfo &info) override;
+ void visit(const FormulaInfo &info) override;
+ void visit(const SparseHistInfo &info) override;
+
+ // Group handling
+ void beginGroup(const char *name) override;
+ void endGroup() override;
// Implement Output
- virtual bool valid() const;
- virtual void begin();
- virtual void end();
+ bool valid() const override;
+ void begin() override;
+ void end() override;
};
std::string ValueToString(Result value, int precision);