sim: Convert power modelling framework to new-style stats

Change-Id: I1dd3ea3d37bb4464637222aa5bc5d88cc7d9b66a
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21143
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
diff --git a/src/sim/clock_domain.cc b/src/sim/clock_domain.cc
index 46dbcba..246ea0e 100644
--- a/src/sim/clock_domain.cc
+++ b/src/sim/clock_domain.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014 ARM Limited
+ * Copyright (c) 2013-2014, 2019 ARM Limited
  * Copyright (c) 2013 Cornell University
  * All rights reserved
  *
@@ -55,20 +55,21 @@
 #include "sim/clocked_object.hh"
 #include "sim/voltage_domain.hh"
 
-void
-ClockDomain::regStats()
+ClockDomain::ClockDomainStats::ClockDomainStats(ClockDomain &cd)
+    : Stats::Group(&cd),
+    ADD_STAT(clock, "Clock period in ticks")
 {
-    SimObject::regStats();
-
-    using namespace Stats;
-
     // Expose the current clock period as a stat for observability in
     // the dumps
-    currentClock
-        .scalar(_clockPeriod)
-        .name(params()->name + ".clock")
-        .desc("Clock period in ticks")
-        ;
+    clock.scalar(cd._clockPeriod);
+}
+
+ClockDomain::ClockDomain(const Params *p, VoltageDomain *voltage_domain)
+    : SimObject(p),
+      _clockPeriod(0),
+      _voltageDomain(voltage_domain),
+      stats(*this)
+{
 }
 
 double
diff --git a/src/sim/clock_domain.hh b/src/sim/clock_domain.hh
index 6ba8b63..bee6bb2 100644
--- a/src/sim/clock_domain.hh
+++ b/src/sim/clock_domain.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2014 ARM Limited
+ * Copyright (c) 2013-2014, 2019 ARM Limited
  * Copyright (c) 2013 Cornell University
  * All rights reserved
  *
@@ -72,14 +72,6 @@
  */
 class ClockDomain : public SimObject
 {
-
-  private:
-
-    /**
-     * Stat to report clock period of clock domain
-     */
-    Stats::Value currentClock;
-
   protected:
 
     /**
@@ -108,12 +100,7 @@
   public:
 
     typedef ClockDomainParams Params;
-    ClockDomain(const Params *p, VoltageDomain *voltage_domain) :
-        SimObject(p),
-        _clockPeriod(0),
-        _voltageDomain(voltage_domain) {}
-
-    void regStats();
+    ClockDomain(const Params *p, VoltageDomain *voltage_domain);
 
     /**
      * Get the clock period.
@@ -157,6 +144,16 @@
     void addDerivedDomain(DerivedClockDomain *clock_domain)
     { children.push_back(clock_domain); }
 
+  private:
+    struct ClockDomainStats : public Stats::Group
+    {
+        ClockDomainStats(ClockDomain &cd);
+
+        /**
+         * Stat to report clock period of clock domain
+         */
+        Stats::Value clock;
+    } stats;
 };
 
 /**
diff --git a/src/sim/clocked_object.cc b/src/sim/clocked_object.cc
index 6982966..32850fe 100644
--- a/src/sim/clocked_object.cc
+++ b/src/sim/clocked_object.cc
@@ -46,7 +46,8 @@
 ClockedObject::ClockedObject(const ClockedObjectParams *p) :
     SimObject(p), Clocked(*p->clk_domain),
     _currPwrState(p->default_p_state),
-    prvEvalTick(0)
+    prvEvalTick(0),
+    stats(*this)
 {
     // Register the power_model with the object
     for (auto & power_model: p->power_model)
@@ -103,7 +104,7 @@
 
     _currPwrState = p;
 
-    numPwrStateTransitions++;
+    stats.numPwrStateTransitions++;
 }
 
 void
@@ -112,13 +113,13 @@
     // Calculate time elapsed from last (valid) state change
     Tick elapsed_time = curTick() - prvEvalTick;
 
-    pwrStateResidencyTicks[_currPwrState] += elapsed_time;
+    stats.pwrStateResidencyTicks[_currPwrState] += elapsed_time;
 
     // Time spent in CLK_GATED state, this might change depending on
     // transition to other low power states in respective simulation
     // objects.
     if (_currPwrState == Enums::PwrState::CLK_GATED) {
-        pwrStateClkGateDist.sample(elapsed_time);
+        stats.pwrStateClkGateDist.sample(elapsed_time);
     }
 
     prvEvalTick = curTick();
@@ -130,7 +131,7 @@
     // Get residency stats
     std::vector<double> ret;
     Stats::VCounter residencies;
-    pwrStateResidencyTicks.value(residencies);
+    stats.pwrStateResidencyTicks.value(residencies);
 
     // Account for current state too!
     Tick elapsed_time = curTick() - prvEvalTick;
@@ -139,38 +140,45 @@
     ret.resize(Enums::PwrState::Num_PwrState);
     for (unsigned i = 0; i < Enums::PwrState::Num_PwrState; i++)
         ret[i] = residencies[i] / \
-                     (pwrStateResidencyTicks.total() + elapsed_time);
+                     (stats.pwrStateResidencyTicks.total() + elapsed_time);
 
     return ret;
 }
 
-void
-ClockedObject::regStats()
+
+ClockedObject::ClockedObjectStats::ClockedObjectStats(ClockedObject &co)
+    : Stats::Group(&co),
+    clockedObject(co),
+    ADD_STAT(numPwrStateTransitions,
+             "Number of power state transitions"),
+    ADD_STAT(pwrStateClkGateDist,
+             "Distribution of time spent in the clock gated state"),
+    ADD_STAT(pwrStateResidencyTicks,
+             "Cumulative time (in ticks) in various power states")
 {
-    SimObject::regStats();
+}
+
+void
+ClockedObject::ClockedObjectStats::regStats()
+{
+    Stats::Group::regStats();
 
     using namespace Stats;
 
-    numPwrStateTransitions
-        .name(params()->name + ".numPwrStateTransitions")
-        .desc("Number of power state transitions")
-        .flags(nozero)
-        ;
+    const ClockedObjectParams *p = clockedObject.params();
+
+    numPwrStateTransitions.flags(nozero);
 
     // Each sample is time in ticks
-    unsigned num_bins = std::max(params()->p_state_clk_gate_bins, 10U);
+    unsigned num_bins = std::max(p->p_state_clk_gate_bins, 10U);
     pwrStateClkGateDist
-        .init(params()->p_state_clk_gate_min, params()->p_state_clk_gate_max,
-          (params()->p_state_clk_gate_max / num_bins))
-        .name(params()->name + ".pwrStateClkGateDist")
-        .desc("Distribution of time spent in the clock gated state")
+        .init(p->p_state_clk_gate_min, p->p_state_clk_gate_max,
+          (p->p_state_clk_gate_max / num_bins))
         .flags(pdf | nozero | nonan)
         ;
 
     pwrStateResidencyTicks
         .init(Enums::PwrState::Num_PwrState)
-        .name(params()->name + ".pwrStateResidencyTicks")
-        .desc("Cumulative time (in ticks) in various power states")
         .flags(nozero)
         ;
     for (int i = 0; i < Enums::PwrState::Num_PwrState; i++) {
@@ -178,6 +186,12 @@
     }
 
     numPwrStateTransitions = 0;
+}
+
+void
+ClockedObject::ClockedObjectStats::preDumpStats()
+{
+    Stats::Group::preDumpStats();
 
     /**
      * For every stats dump, the power state residency and other distribution
@@ -187,5 +201,5 @@
      * next dump window which might have rather unpleasant effects (like
      * perturbing the distribution stats).
      */
-    registerDumpCallback(new ClockedObjectDumpCallback(this));
+    clockedObject.computeStats();
 }
diff --git a/src/sim/clocked_object.hh b/src/sim/clocked_object.hh
index d41f71a..ba1750e 100644
--- a/src/sim/clocked_object.hh
+++ b/src/sim/clocked_object.hh
@@ -270,7 +270,6 @@
     void computeStats();
 
     void pwrState(Enums::PwrState);
-    void regStats() override;
 
   protected:
 
@@ -279,18 +278,18 @@
 
     Tick prvEvalTick;
 
-    Stats::Scalar numPwrStateTransitions;
-    Stats::Distribution pwrStateClkGateDist;
-    Stats::Vector pwrStateResidencyTicks;
+    struct ClockedObjectStats : public Stats::Group
+    {
+        ClockedObjectStats(ClockedObject &co);
 
-};
+        void regStats() override;
+        void preDumpStats() override;
 
-class ClockedObjectDumpCallback : public Callback
-{
-    ClockedObject *co;
-  public:
-    ClockedObjectDumpCallback(ClockedObject *co_t) : co(co_t) {}
-    virtual void process() { co->computeStats(); };
+        ClockedObject &clockedObject;
+        Stats::Scalar numPwrStateTransitions;
+        Stats::Distribution pwrStateClkGateDist;
+        Stats::Vector pwrStateResidencyTicks;
+    } stats;
 };
 
 #endif //__SIM_CLOCKED_OBJECT_HH__
diff --git a/src/sim/voltage_domain.cc b/src/sim/voltage_domain.cc
index 6f32dc7..ca86478 100644
--- a/src/sim/voltage_domain.cc
+++ b/src/sim/voltage_domain.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014 ARM Limited
+ * Copyright (c) 2012-2014, 2019 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -49,7 +49,7 @@
 #include "sim/sim_object.hh"
 
 VoltageDomain::VoltageDomain(const Params *p)
-    : SimObject(p), voltageOpPoints(p->voltage), _perfLevel(0)
+    : SimObject(p), voltageOpPoints(p->voltage), _perfLevel(0), stats(*this)
 {
     fatal_if(voltageOpPoints.empty(), "DVFS: Empty set of voltages for "\
              "voltage domain %s\n", name());
@@ -127,18 +127,6 @@
     }
 }
 
-void
-VoltageDomain::regStats()
-{
-    SimObject::regStats();
-
-    currentVoltage
-        .method(this, &VoltageDomain::voltage)
-        .name(params()->name + ".voltage")
-        .desc("Voltage in Volts")
-        ;
-}
-
 VoltageDomain *
 VoltageDomainParams::create()
 {
@@ -157,3 +145,10 @@
     UNSERIALIZE_SCALAR(_perfLevel);
     perfLevel(_perfLevel);
 }
+
+VoltageDomain::VoltageDomainStats::VoltageDomainStats(VoltageDomain &vd)
+    : Stats::Group(&vd),
+    ADD_STAT(voltage, "Voltage in Volts")
+{
+    voltage.method(&vd, &VoltageDomain::voltage);
+}
diff --git a/src/sim/voltage_domain.hh b/src/sim/voltage_domain.hh
index e7e4f81..2702647 100644
--- a/src/sim/voltage_domain.hh
+++ b/src/sim/voltage_domain.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012, 2019 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -126,8 +126,6 @@
      */
     bool sanitiseVoltages();
 
-    void regStats() override;
-
     void serialize(CheckpointOut &cp) const override;
     void unserialize(CheckpointIn &cp) override;
 
@@ -143,10 +141,15 @@
     const Voltages voltageOpPoints;
     PerfLevel _perfLevel;
 
-    /**
-     * Stat for reporting voltage of the domain
-     */
-    Stats::Value currentVoltage;
+    struct VoltageDomainStats : public Stats::Group
+    {
+        VoltageDomainStats(VoltageDomain &vd);
+
+        /**
+         * Stat for reporting voltage of the domain
+         */
+        Stats::Value voltage;
+    } stats;
 
     /**
      * List of associated SrcClockDomains that are connected to this voltage