Daniel Carvalho has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/38700 )

Change subject: sim: Move management responsibility from probe listener
......................................................................

sim: Move management responsibility from probe listener

Listeners always relate to a specific probe points; thus,
their management should be done by the points, not from
the listeners themselves.

Explicitly call the probe manager to create new listeners,
and use smart pointers to manage them. This fixes memory
leaks within the probes of the mem dir.

As a side effect, renamed attachedProbePointList to listeners,
since it is a vector of probe listeners, not probe points.

As a side effect, removed the duplicated/unused vectors of
listener pointers.

Jira: https://gem5.atlassian.net/browse/GEM5-857

Change-Id: Ib7d70cb51d346987ba4b0e7f969aa0274f19a3e4
Signed-off-by: Daniel R. Carvalho <oda...@yahoo.com.br>
---
M src/arch/arm/pmu.cc
M src/arch/arm/pmu.hh
M src/cpu/o3/probe/elastic_trace.cc
M src/cpu/o3/probe/simple_trace.cc
M src/cpu/simple/probes/simpoint.cc
M src/mem/cache/compressors/frequent_values.cc
M src/mem/cache/compressors/frequent_values.hh
M src/mem/cache/prefetch/base.cc
M src/mem/cache/prefetch/base.hh
M src/mem/cache/prefetch/pif.cc
M src/mem/cache/prefetch/pif.hh
M src/mem/probes/base.cc
M src/mem/probes/base.hh
M src/sim/power/power_model.cc
M src/sim/power/power_model.hh
M src/sim/probe/probe.cc
M src/sim/probe/probe.hh
17 files changed, 110 insertions(+), 146 deletions(-)



diff --git a/src/arch/arm/pmu.cc b/src/arch/arm/pmu.cc
index 6de7a8e..5d87ccc 100644
--- a/src/arch/arm/pmu.cc
+++ b/src/arch/arm/pmu.cc
@@ -474,7 +474,7 @@
 void
 PMU::RegularEvent::enable()
 {
-    for (auto &listener : attachedProbePointList) {
+    for (auto &listener : listeners) {
         listener->enable();
     }
 }
@@ -482,7 +482,7 @@
 void
 PMU::RegularEvent::disable()
 {
-    for (auto &listener : attachedProbePointList) {
+    for (auto &listener : listeners) {
         listener->disable();
     }
 }
diff --git a/src/arch/arm/pmu.hh b/src/arch/arm/pmu.hh
index 65781b8..8bffef2 100644
--- a/src/arch/arm/pmu.hh
+++ b/src/arch/arm/pmu.hh
@@ -347,17 +347,17 @@
         {
             panic_if(!object,"malformed probe-point"
                 " definition with name %s\n", name);
-            attachedProbePointList.emplace_back(
-                new RegularProbe(this, object, name));
+            auto listener = new RegularProbe(this);
+            object->getProbeManager()->addListener(name, listener);
+            listeners.emplace_back(listener);
         }

       protected:
         struct RegularProbe: public  ProbeListenerArgBase<uint64_t>
         {
-            RegularProbe(RegularEvent *parent, SimObject* obj,
-                std::string name)
-                : ProbeListenerArgBase(obj->getProbeManager(), name),
-                  parentEvent(parent) {}
+            RegularProbe(RegularEvent *parent)
+              : ProbeListenerArgBase(), parentEvent(parent)
+            {}

             RegularProbe() = delete;

@@ -367,10 +367,12 @@
             RegularEvent *parentEvent;
         };

- /** Set of probe listeners tapping onto each of the input micro-arch
-         *  events which compose this pmu event
+        /**
+         * Set of probe listeners tapping onto each of the input micro-arch
+         * events which compose this pmu event.
+         * These pointers are managed by the probe.
          */
-        std::vector<std::unique_ptr<RegularProbe>> attachedProbePointList;
+        std::vector<RegularProbe*> listeners;

         void enable() override;

diff --git a/src/cpu/o3/probe/elastic_trace.cc b/src/cpu/o3/probe/elastic_trace.cc
index aee97bd..9ef32df 100644
--- a/src/cpu/o3/probe/elastic_trace.cc
+++ b/src/cpu/o3/probe/elastic_trace.cc
@@ -37,6 +37,8 @@

 #include "cpu/o3/probe/elastic_trace.hh"

+#include <memory>
+
 #include "base/callback.hh"
 #include "base/output.hh"
 #include "base/trace.hh"
@@ -117,25 +119,27 @@
         " probe listeners", curTick(), cpu->numSimulatedInsts());
// Create new listeners: provide method to be called upon a notify() for
     // each probe point.
- listeners.push_back(new ProbeListenerArg<ElasticTrace, RequestPtr>(this,
-                        "FetchRequest", &ElasticTrace::fetchReqTrace));
-    listeners.push_back(new ProbeListenerArg<ElasticTrace,
-            DynInstConstPtr>(this, "Execute",
-                &ElasticTrace::recordExecTick));
-    listeners.push_back(new ProbeListenerArg<ElasticTrace,
-            DynInstConstPtr>(this, "ToCommit",
-                &ElasticTrace::recordToCommTick));
-    listeners.push_back(new ProbeListenerArg<ElasticTrace,
-            DynInstConstPtr>(this, "Rename",
-                &ElasticTrace::updateRegDep));
- listeners.push_back(new ProbeListenerArg<ElasticTrace, SeqNumRegPair>(this, - "SquashInRename", &ElasticTrace::removeRegDepMapEntry));
-    listeners.push_back(new ProbeListenerArg<ElasticTrace,
-            DynInstConstPtr>(this, "Squash",
-                &ElasticTrace::addSquashedInst));
-    listeners.push_back(new ProbeListenerArg<ElasticTrace,
-            DynInstConstPtr>(this, "Commit",
-                &ElasticTrace::addCommittedInst));
+    getProbeManager()->addListener("FetchRequest",
+        new ProbeListenerArg<ElasticTrace, RequestPtr>(
+        this, &ElasticTrace::fetchReqTrace));
+    getProbeManager()->addListener("Execute",
+        new ProbeListenerArg<ElasticTrace, DynInstConstPtr>(
+        this, &ElasticTrace::recordExecTick));
+    getProbeManager()->addListener("ToCommit",
+        new ProbeListenerArg<ElasticTrace, DynInstConstPtr>(
+        this, &ElasticTrace::recordToCommTick));
+    getProbeManager()->addListener("Rename",
+        new ProbeListenerArg<ElasticTrace, DynInstConstPtr>(
+        this, &ElasticTrace::updateRegDep));
+    getProbeManager()->addListener("SquashInRename",
+        new ProbeListenerArg<ElasticTrace, SeqNumRegPair>(
+        this, &ElasticTrace::removeRegDepMapEntry));
+    getProbeManager()->addListener("Squash",
+        new ProbeListenerArg<ElasticTrace, DynInstConstPtr>(
+        this, &ElasticTrace::addSquashedInst));
+    getProbeManager()->addListener("Commit",
+        new ProbeListenerArg<ElasticTrace, DynInstConstPtr>(
+        this, &ElasticTrace::addCommittedInst));
     allProbesReg = true;
 }

diff --git a/src/cpu/o3/probe/simple_trace.cc b/src/cpu/o3/probe/simple_trace.cc
index cc4ccea..bf3508d 100644
--- a/src/cpu/o3/probe/simple_trace.cc
+++ b/src/cpu/o3/probe/simple_trace.cc
@@ -37,6 +37,8 @@

 #include "cpu/o3/probe/simple_trace.hh"

+#include <memory>
+
 #include "base/trace.hh"
 #include "debug/SimpleTrace.hh"

@@ -58,8 +60,8 @@
 {
     typedef ProbeListenerArg<SimpleTrace,
             O3CPUImpl::DynInstConstPtr> DynInstListener;
-    listeners.push_back(new DynInstListener(this, "Commit",
-                &SimpleTrace::traceCommit));
-    listeners.push_back(new DynInstListener(this, "Fetch",
-                &SimpleTrace::traceFetch));
+    getProbeManager()->addListener("Commit", new DynInstListener(this,
+        &SimpleTrace::traceCommit));
+    getProbeManager()->addListener("Fetch", new DynInstListener(this,
+        &SimpleTrace::traceFetch));
 }
diff --git a/src/cpu/simple/probes/simpoint.cc b/src/cpu/simple/probes/simpoint.cc
index d835b2b..d495d8c 100644
--- a/src/cpu/simple/probes/simpoint.cc
+++ b/src/cpu/simple/probes/simpoint.cc
@@ -37,6 +37,8 @@

 #include "cpu/simple/probes/simpoint.hh"

+#include <memory>
+
 #include "base/output.hh"

 SimPoint::SimPoint(const SimPointParams &p)
@@ -67,8 +69,8 @@
 {
typedef ProbeListenerArg<SimPoint, std::pair<SimpleThread*,StaticInstPtr>>
         SimPointListener;
-    listeners.push_back(new SimPointListener(this, "Commit",
-                                             &SimPoint::profile));
+    getProbeManager()->addListener("Commit",
+        new SimPointListener(this, &SimPoint::profile));
 }

 void
diff --git a/src/mem/cache/compressors/frequent_values.cc b/src/mem/cache/compressors/frequent_values.cc
index 2806e31..a89f437 100644
--- a/src/mem/cache/compressors/frequent_values.cc
+++ b/src/mem/cache/compressors/frequent_values.cc
@@ -282,16 +282,9 @@
 void
 FrequentValues::regProbeListeners()
 {
-    assert(listeners.empty());
     assert(cache != nullptr);
-    listeners.push_back(new FrequentValuesListener(
-        *this, cache->getProbeManager(), "Data Update"));
-}
-
-void
-FrequentValues::FrequentValuesListener::notify(const DataUpdate &data_update)
-{
-    parent.probeNotify(data_update);
+    cache->getProbeManager()->addListener("Data Update",
+        new FrequentValuesListener(*this));
 }

 } // namespace Compressor
diff --git a/src/mem/cache/compressors/frequent_values.hh b/src/mem/cache/compressors/frequent_values.hh
index 0624759..e09be8a 100644
--- a/src/mem/cache/compressors/frequent_values.hh
+++ b/src/mem/cache/compressors/frequent_values.hh
@@ -67,14 +67,17 @@
         FrequentValues &parent;

       public:
-        FrequentValuesListener(FrequentValues &_parent, ProbeManager *pm,
-            const std::string &name)
-          : ProbeListenerArgBase(pm, name), parent(_parent)
+        FrequentValuesListener(FrequentValues &_parent)
+          : ProbeListenerArgBase(), parent(_parent)
         {
         }
-        void notify(const DataUpdate &data_update) override;
+
+        void
+        notify(const DataUpdate &data_update) override
+        {
+            parent.probeNotify(data_update);
+        }
     };
-    std::vector<FrequentValuesListener*> listeners;

     /** Whether Huffman encoding is applied to the VFT indices. */
     const bool useHuffmanEncoding;
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index 28aaa62..7bb2231 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -89,7 +89,7 @@
 }

 Base::Base(const BasePrefetcherParams &p)
-    : ClockedObject(p), listeners(), cache(nullptr), blkSize(p.block_size),
+    : ClockedObject(p), cache(nullptr), blkSize(p.block_size),
       lBlkSize(floorLog2(blkSize)), onMiss(p.on_miss), onRead(p.on_read),
       onWrite(p.on_write), onData(p.on_data), onInst(p.on_inst),
       requestorId(p.sys->getRequestorId(this)),
@@ -230,15 +230,12 @@
      * parent cache using the probe "Miss". Also connect to "Hit", if the
      * cache is configured to prefetch on accesses.
      */
-    if (listeners.empty() && cache != nullptr) {
+    if (cache != nullptr) {
         ProbeManager *pm(cache->getProbeManager());
-        listeners.push_back(new PrefetchListener(*this, pm, "Miss", false,
-                                                true));
-        listeners.push_back(new PrefetchListener(*this, pm, "Fill", true,
-                                                 false));
+        pm->addListener("Miss", new PrefetchListener(*this, false, true));
+        pm->addListener("Fill", new PrefetchListener(*this, true, false));
         if (prefetchOnAccess) {
- listeners.push_back(new PrefetchListener(*this, pm, "Hit", false,
-                                                     false));
+ pm->addListener("Hit", new PrefetchListener(*this, false, false));
         }
     }
 }
@@ -246,8 +243,7 @@
 void
 Base::addEventProbe(SimObject *obj, const char *name)
 {
-    ProbeManager *pm(obj->getProbeManager());
-    listeners.push_back(new PrefetchListener(*this, pm, name));
+    obj->getProbeManager()->addListener(name, new PrefetchListener(*this));
 }

 void
diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh
index 2dcc95f..9b728d8 100644
--- a/src/mem/cache/prefetch/base.hh
+++ b/src/mem/cache/prefetch/base.hh
@@ -47,6 +47,7 @@
 #define __MEM_CACHE_PREFETCH_BASE_HH__

 #include <cstdint>
+#include <memory>

 #include "arch/generic/tlb.hh"
 #include "base/statistics.hh"
@@ -67,20 +68,18 @@
     class PrefetchListener : public ProbeListenerArgBase<PacketPtr>
     {
       public:
-        PrefetchListener(Base &_parent, ProbeManager *pm,
-                         const std::string &name, bool _isFill = false,
-                         bool _miss = false)
-            : ProbeListenerArgBase(pm, name),
-              parent(_parent), isFill(_isFill), miss(_miss) {}
+ PrefetchListener(Base &_parent, bool _isFill=false, bool _miss=false)
+          : ProbeListenerArgBase(),
+            parent(_parent), isFill(_isFill), miss(_miss)
+        {}
         void notify(const PacketPtr &pkt) override;
+
       protected:
         Base &parent;
         const bool isFill;
         const bool miss;
     };

-    std::vector<PrefetchListener *> listeners;
-
   public:

     /**
diff --git a/src/mem/cache/prefetch/pif.cc b/src/mem/cache/prefetch/pif.cc
index c349dac..2bce80d 100644
--- a/src/mem/cache/prefetch/pif.cc
+++ b/src/mem/cache/prefetch/pif.cc
@@ -44,8 +44,7 @@
       historyBuffer(p.history_buffer_size),
       index(p.index_assoc, p.index_entries, p.index_indexing_policy,
             p.index_replacement_policy),
-      streamAddressBuffer(p.stream_address_buffer_entries),
-      listenersPC()
+      streamAddressBuffer(p.stream_address_buffer_entries)
 {
 }

@@ -239,8 +238,7 @@
 void
 PIF::addEventProbeRetiredInsts(SimObject *obj, const char *name)
 {
-    ProbeManager *pm(obj->getProbeManager());
-    listenersPC.push_back(new PrefetchListenerPC(*this, pm, name));
+ obj->getProbeManager()->addListener(name, new PrefetchListenerPC(*this));
 }

 } // namespace Prefetcher
diff --git a/src/mem/cache/prefetch/pif.hh b/src/mem/cache/prefetch/pif.hh
index fffa39b..b1589c5 100644
--- a/src/mem/cache/prefetch/pif.hh
+++ b/src/mem/cache/prefetch/pif.hh
@@ -38,6 +38,7 @@
 #define __MEM_CACHE_PREFETCH_PIF_HH__

 #include <deque>
+#include <memory>
 #include <vector>

 #include "base/circular_queue.hh"
@@ -159,19 +160,15 @@
         class PrefetchListenerPC : public ProbeListenerArgBase<Addr>
         {
           public:
-            PrefetchListenerPC(PIF &_parent, ProbeManager *pm,
-                             const std::string &name)
-                : ProbeListenerArgBase(pm, name),
-                  parent(_parent) {}
+            PrefetchListenerPC(PIF &_parent)
+              : ProbeListenerArgBase(), parent(_parent)
+            {}
             void notify(const Addr& pc) override;
+
           protected:
             PIF &parent;
         };

-        /** Array of probe listeners */
-        std::vector<PrefetchListenerPC *> listenersPC;
-
-
     public:
         PIF(const PIFPrefetcherParams &p);
         ~PIF() = default;
diff --git a/src/mem/probes/base.cc b/src/mem/probes/base.cc
index 7ea63dc..9b012ee 100644
--- a/src/mem/probes/base.cc
+++ b/src/mem/probes/base.cc
@@ -50,9 +50,8 @@
     const BaseMemProbeParams &p =
         dynamic_cast<const BaseMemProbeParams &>(params());

-    listeners.resize(p.manager.size());
     for (int i = 0; i < p.manager.size(); i++) {
         ProbeManager *const mgr(p.manager[i]->getProbeManager());
-        listeners[i].reset(new PacketListener(*this, mgr, p.probe_name));
+        mgr->addListener(p.probe_name, new PacketListener(*this));
     }
 }
diff --git a/src/mem/probes/base.hh b/src/mem/probes/base.hh
index 64b8a56..18e6855 100644
--- a/src/mem/probes/base.hh
+++ b/src/mem/probes/base.hh
@@ -75,20 +75,19 @@
class PacketListener : public ProbeListenerArgBase<ProbePoints::PacketInfo>
     {
       public:
-        PacketListener(BaseMemProbe &_parent,
-                       ProbeManager *pm, const std::string &name)
-            : ProbeListenerArgBase(pm, name),
-              parent(_parent) {}
+        PacketListener(BaseMemProbe &_parent)
+          : ProbeListenerArgBase(), parent(_parent)
+        {}

-        void notify(const ProbePoints::PacketInfo &pkt_info) override {
+        void
+        notify(const ProbePoints::PacketInfo &pkt_info) override
+        {
             parent.handleRequest(pkt_info);
         }

       protected:
         BaseMemProbe &parent;
     };
-
-    std::vector<std::unique_ptr<PacketListener>> listeners;
 };

 #endif //  __MEM_PROBES_BASE_HH__
diff --git a/src/sim/power/power_model.cc b/src/sim/power/power_model.cc
index fbc67d3..111d7d8 100644
--- a/src/sim/power/power_model.cc
+++ b/src/sim/power/power_model.cc
@@ -95,9 +95,8 @@
 void
 PowerModel::regProbePoints()
 {
-    thermalListener.reset(new ThermalProbeListener (
-        *this, this->subsystem->getProbeManager(), "thermalUpdate"
-    ));
+    this->subsystem->getProbeManager()->addListener("thermalUpdate",
+        new ThermalProbeListener(*this));
 }

 double
diff --git a/src/sim/power/power_model.hh b/src/sim/power/power_model.hh
index e6f5431..8362531 100644
--- a/src/sim/power/power_model.hh
+++ b/src/sim/power/power_model.hh
@@ -132,9 +132,9 @@
     class ThermalProbeListener : public ProbeListenerArgBase<double>
     {
       public:
-        ThermalProbeListener(PowerModel &_pm, ProbeManager *pm,
-                      const std::string &name)
-            : ProbeListenerArgBase(pm, name), pm(_pm) {}
+        ThermalProbeListener(PowerModel &_pm)
+          : ProbeListenerArgBase(), pm(_pm)
+        {}

         void notify(const double &temp)
         {
@@ -148,9 +148,6 @@
     /** Actual power models (one per power state) */
     std::vector<PowerModelState*> states_pm;

-    /** Listener to catch temperature changes in the SubSystem */
-    std::unique_ptr<ThermalProbeListener> thermalListener;
-
     /** The subsystem this power model belongs to */
     SubSystem * subsystem;

diff --git a/src/sim/probe/probe.cc b/src/sim/probe/probe.cc
index 656ea8e..01fcc85 100644
--- a/src/sim/probe/probe.cc
+++ b/src/sim/probe/probe.cc
@@ -57,34 +57,15 @@
         "The probe manager of %s has not been instantiated", name());
 }

-ProbeListenerObject::~ProbeListenerObject()
-{
-    for (auto l = listeners.begin(); l != listeners.end(); ++l) {
-        delete (*l);
-    }
-    listeners.clear();
-}
-
-ProbeListener::ProbeListener(ProbeManager *_manager, const std::string &_name)
-    : manager(_manager), name(_name), _enabled(true)
-{
-    manager->addListener(name, *this);
-}
-
-ProbeListener::~ProbeListener()
-{
-    manager->removeListener(name, *this);
-}
-
 bool
-ProbeManager::addListener(std::string point_name, ProbeListener &listener)
+ProbeManager::addListener(std::string point_name, ProbeListener *listener)
 {
DPRINTFR(ProbeVerbose, "Probes: Call to addListener to \"%s\" on %s.\n",
         point_name, object->name());
     bool added = false;
     for (auto p = points.begin(); p != points.end(); ++p) {
         if ((*p)->getName() == point_name) {
-            (*p)->addListener(&listener);
+            (*p)->addListener(listener);
             added = true;
         }
     }
@@ -96,14 +77,14 @@
 }

 bool
-ProbeManager::removeListener(std::string point_name, ProbeListener &listener) +ProbeManager::removeListener(std::string point_name, ProbeListener *listener)
 {
     DPRINTFR(ProbeVerbose, "Probes: Call to removeListener from \"%s\" on "
         "%s.\n", point_name, object->name());
     bool removed = false;
     for (auto p = points.begin(); p != points.end(); ++p) {
         if ((*p)->getName() == point_name) {
-            (*p)->removeListener(&listener);
+            (*p)->removeListener(listener);
             removed = true;
         }
     }
diff --git a/src/sim/probe/probe.hh b/src/sim/probe/probe.hh
index 5c72126..36f5b86 100644
--- a/src/sim/probe/probe.hh
+++ b/src/sim/probe/probe.hh
@@ -63,6 +63,8 @@
 #ifndef __SIM_PROBE_PROBE_HH__
 #define __SIM_PROBE_PROBE_HH__

+#include <algorithm>
+#include <memory>
 #include <string>
 #include <vector>

@@ -97,18 +99,15 @@
  * SimObject.
  *
  * It instantiates manager from a call to Parent.any.
- * The vector of listeners is used simply to hold onto listeners until the
- * ProbeListenerObject is destroyed.
  */
 class ProbeListenerObject : public SimObject
 {
   protected:
     ProbeManager *manager;
-    std::vector<ProbeListener *> listeners;

   public:
     ProbeListenerObject(const ProbeListenerObjectParams &params);
-    virtual ~ProbeListenerObject();
+    virtual ~ProbeListenerObject() = default;
     ProbeManager* getProbeManager() { return manager; }
 };

@@ -116,14 +115,13 @@
  * ProbeListener base class; here to simplify things like containers
  * containing multiple types of ProbeListener.
  *
- * Note a ProbeListener is added to the ProbePoint in constructor by
- * using the ProbeManager passed in.
+ * Every new probe listener must be added to the probe manager.
  */
 class ProbeListener
 {
   public:
-    ProbeListener(ProbeManager *manager, const std::string &name);
-    virtual ~ProbeListener();
+    ProbeListener() : _enabled(true) {}
+    virtual ~ProbeListener() = default;
     ProbeListener(const ProbeListener& other) = delete;
     ProbeListener& operator=(const ProbeListener& other) = delete;
     ProbeListener(ProbeListener&& other) noexcept = delete;
@@ -143,10 +141,6 @@
      */
     bool enabled() const { return _enabled; }

-  protected:
-    ProbeManager *const manager;
-    const std::string name;
-
   private:
     /** Whether this listener processes notifications. */
     bool _enabled;
@@ -195,7 +189,7 @@
      * @param listener the ProbeListener to add.
      * @return true if added, false otherwise.
      */
-    bool addListener(std::string point_name, ProbeListener &listener);
+    bool addListener(std::string point_name, ProbeListener *listener);

     /**
* @brief Remove a ProbeListener from the ProbePoint named by pointName.
@@ -205,7 +199,7 @@
      * @param listener the ProbeListener to remove.
      * @return true if removed, false otherwise.
      */
-    bool removeListener(std::string point_name, ProbeListener &listener);
+    bool removeListener(std::string point_name, ProbeListener *listener);

     /**
      * @brief Create and add a ProbePoint to this SimObject's ProbeManager.
@@ -245,9 +239,7 @@
 class ProbeListenerArgBase : public ProbeListener
 {
   public:
-    ProbeListenerArgBase(ProbeManager *pm, const std::string &name)
-        : ProbeListener(pm, name)
-    {}
+    ProbeListenerArgBase() : ProbeListener() {}
     virtual void notify(const Arg &val) = 0;
 };

@@ -271,9 +263,8 @@
      * @param name the name of the ProbePoint to add this listener to.
      * @param func a pointer to the function on obj (called on notify).
      */
-    ProbeListenerArg(T *obj, const std::string &name,
-        void (T::* func)(const Arg &))
-        : ProbeListenerArgBase<Arg>(obj->getProbeManager(), name),
+    ProbeListenerArg(T *obj, void (T::* func)(const Arg &))
+        : ProbeListenerArgBase<Arg>(),
           object(obj),
           function(func)
     {}
@@ -297,7 +288,7 @@
 class ProbePointArg : public ProbePoint
 {
     /** The attached listeners. */
-    std::vector<ProbeListenerArgBase<Arg> *> listeners;
+    std::vector<std::shared_ptr<ProbeListenerArgBase<Arg>>> listeners;

   public:
     ProbePointArg(std::string name)
@@ -322,9 +313,10 @@
     addListener(ProbeListener *l) override
     {
         // check listener not already added
-        if (std::find(listeners.begin(), listeners.end(), l) ==
-            listeners.end()) {
- listeners.push_back(static_cast<ProbeListenerArgBase<Arg> *>(l)); + if (listeners.end() == std::find_if(listeners.begin(), listeners.end(), + [l](const std::shared_ptr<ProbeListenerArgBase<Arg>> &listener) ->
+                bool { return listener.get() == l; })) {
+ listeners.emplace_back(static_cast<ProbeListenerArgBase<Arg>*>(l));
         }
     }

@@ -335,8 +327,9 @@
     void
     removeListener(ProbeListener *l) override
     {
-        listeners.erase(std::remove(listeners.begin(), listeners.end(), l),
-                        listeners.end());
+        listeners.erase(std::remove_if(listeners.begin(), listeners.end(),
+ [l](const std::shared_ptr<ProbeListenerArgBase<Arg>> &listener) ->
+                bool { return listener.get() == l; }), listeners.end());
     }

     /**

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/38700
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ib7d70cb51d346987ba4b0e7f969aa0274f19a3e4
Gerrit-Change-Number: 38700
Gerrit-PatchSet: 1
Gerrit-Owner: Daniel Carvalho <oda...@yahoo.com.br>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to