base: add support for probe points and common probes
authorMatt Horsnell <matt.horsnell@ARM.com>
Fri, 24 Jan 2014 21:29:30 +0000 (15:29 -0600)
committerMatt Horsnell <matt.horsnell@ARM.com>
Fri, 24 Jan 2014 21:29:30 +0000 (15:29 -0600)
The probe patch is motivated by the desire to move analytical and trace code
away from functional code. This is achieved by the probe interface which is
essentially a glorified observer model.

What this means to users:
* add a probe point and a "notify" call at the source of an "event"
* add an isolated module, that is being used to carry out *your* analysis (e.g. generate a trace)
* register that module as a probe listener
Note: an example is given for reference in src/cpu/o3/simple_trace.[hh|cc] and src/cpu/SimpleTrace.py

What is happening under the hood:
* every SimObject maintains has a ProbeManager.
* during initialization (src/python/m5/simulate.py) first regProbePoints and
  the regProbeListeners is called on each SimObject.  this hooks up the probe
  point notify calls with the listeners.

FAQs:
Why did you develop probe points:
* to remove trace, stats gathering, analytical code out of the functional code.
* the belief that probes could be generically useful.

What is a probe point:
* a probe point is used to notify upon a given event (e.g. cpu commits an instruction)

What is a probe listener:
* a class that handles whatever the user wishes to do when they are notified
  about an event.

What can be passed on notify:
* probe points are templates, and so the user can generate probes that pass any
  type of argument (by const reference) to a listener.

What relationships can be generated (1:1, 1:N, N:M etc):
* there isn't a restriction. You can hook probe points and listeners up in a
  1:1, 1:N, N:M relationship. They become useful when a number of modules
  listen to the same probe points. The idea being that you can add a small
  number of probes into the source code and develop a larger number of useful
  analysis modules that use information passed by the probes.

Can you give examples:
* adding a probe point to the cpu's commit method allows you to build a trace
  module (outputting assembler), you could re-use this to gather instruction
  distribution (arithmetic, load/store, conditional, control flow) stats.

Why is the probe interface currently restricted to passing a const reference:
* the desire, initially at least, is to allow an interface to observe
  functionality, but not to change functionality.
* of course this can be subverted by const-casting.

What is the performance impact of adding probes:
* when nothing is actively listening to the probes they should have a
  relatively minor impact. Profiling has suggested even with a large number of
  probes (60) the impact of them (when not active) is very minimal (<1%).

21 files changed:
src/cpu/o3/commit.hh
src/cpu/o3/commit_impl.hh
src/cpu/o3/cpu.cc
src/cpu/o3/cpu.hh
src/cpu/o3/fetch.hh
src/cpu/o3/fetch_impl.hh
src/cpu/o3/iew.hh
src/cpu/o3/iew_impl.hh
src/cpu/o3/lsq_unit_impl.hh
src/cpu/o3/probe/SConscript [new file with mode: 0644]
src/cpu/o3/probe/SimpleTrace.py [new file with mode: 0644]
src/cpu/o3/probe/simple_trace.cc [new file with mode: 0644]
src/cpu/o3/probe/simple_trace.hh [new file with mode: 0644]
src/python/m5/SimObject.py
src/python/m5/simulate.py
src/sim/probe/Probe.py [new file with mode: 0644]
src/sim/probe/SConscript [new file with mode: 0644]
src/sim/probe/probe.cc [new file with mode: 0644]
src/sim/probe/probe.hh [new file with mode: 0644]
src/sim/sim_object.cc
src/sim/sim_object.hh

index 62aa274c2c0f493bdf190620703c1f83b729df9d..cd663e2df6ad898062b3ebf6742af7992a7a23dd 100644 (file)
@@ -50,6 +50,7 @@
 #include "cpu/exetrace.hh"
 #include "cpu/inst_seq.hh"
 #include "cpu/timebuf.hh"
+#include "sim/probe/probe.hh"
 
 struct DerivO3CPUParams;
 
@@ -150,6 +151,10 @@ class DefaultCommit
     /** Commit policy used in SMT mode. */
     CommitPolicy commitPolicy;
 
+    /** Probe Points. */
+    ProbePointArg<DynInstPtr> *ppCommit;
+    ProbePointArg<DynInstPtr> *ppCommitStall;
+
   public:
     /** Construct a DefaultCommit with the given parameters. */
     DefaultCommit(O3CPU *_cpu, DerivO3CPUParams *params);
@@ -160,6 +165,9 @@ class DefaultCommit
     /** Registers statistics. */
     void regStats();
 
+    /** Registers probes. */
+    void regProbePoints();
+
     /** Sets the list of threads. */
     void setThreads(std::vector<Thread *> &threads);
 
index 6664faf95e3f98f7ec0f44b850f9017d04cb6eb6..a6f2a63db35cbe9eb670b91f487288af81af7c02 100644 (file)
@@ -161,6 +161,14 @@ DefaultCommit<Impl>::name() const
     return cpu->name() + ".commit";
 }
 
+template <class Impl>
+void
+DefaultCommit<Impl>::regProbePoints()
+{
+    ppCommit = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Commit");
+    ppCommitStall = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "CommitStall");
+}
+
 template <class Impl>
 void
 DefaultCommit<Impl>::regStats()
@@ -705,6 +713,8 @@ DefaultCommit<Impl>::tick()
         } else if (!rob->isEmpty(tid)) {
             DynInstPtr inst = rob->readHeadInst(tid);
 
+            ppCommitStall->notify(inst);
+
             DPRINTF(Commit,"[tid:%i]: Can't commit, Instruction [sn:%lli] PC "
                     "%s is head of ROB and not ready\n",
                     tid, inst->seqNum, inst->pcState());
@@ -1017,6 +1027,7 @@ DefaultCommit<Impl>::commitInsts()
 
             if (commit_success) {
                 ++num_committed;
+                ppCommit->notify(head_inst);
 
                 changedROBNumEntries[tid] = true;
 
index 515d87f1b7e59d268825b664c379c3e8e9db195b..710482d3c83d1a67f58030023c2a4454fb198ac2 100644 (file)
@@ -466,6 +466,17 @@ FullO3CPU<Impl>::~FullO3CPU()
 {
 }
 
+template <class Impl>
+void
+FullO3CPU<Impl>::regProbePoints()
+{
+    ppInstAccessComplete = new ProbePointArg<PacketPtr>(getProbeManager(), "InstAccessComplete");
+    ppDataAccessComplete = new ProbePointArg<std::pair<DynInstPtr, PacketPtr> >(getProbeManager(), "DataAccessComplete");
+    fetch.regProbePoints();
+    iew.regProbePoints();
+    commit.regProbePoints();
+}
+
 template <class Impl>
 void
 FullO3CPU<Impl>::regStats()
index 18b75948f7613fc11937703d23e2d798057dda87..dadee5d56e8d64b85bdc9aa72c4ceea926d1091a 100644 (file)
@@ -375,6 +375,12 @@ class FullO3CPU : public BaseO3CPU
     /** Registers statistics. */
     void regStats();
 
+    ProbePointArg<PacketPtr> *ppInstAccessComplete;
+    ProbePointArg<std::pair<DynInstPtr, PacketPtr> > *ppDataAccessComplete;
+
+    /** Register probe points. */
+    void regProbePoints();
+
     void demapPage(Addr vaddr, uint64_t asn)
     {
         this->itb->demapPage(vaddr, asn);
index 6ef604af3fb907789ee05d05a7e302be4ada4f8b..eba4469c0a01e56d95006bb2a06eb40eaee6584e 100644 (file)
@@ -55,6 +55,7 @@
 #include "mem/packet.hh"
 #include "mem/port.hh"
 #include "sim/eventq.hh"
+#include "sim/probe/probe.hh"
 
 struct DerivO3CPUParams;
 
@@ -194,6 +195,9 @@ class DefaultFetch
     /** List that has the threads organized by priority. */
     std::list<ThreadID> priorityList;
 
+    /** Probe points. */
+    ProbePointArg<DynInstPtr> *ppFetch;
+
   public:
     /** DefaultFetch constructor. */
     DefaultFetch(O3CPU *_cpu, DerivO3CPUParams *params);
@@ -204,6 +208,9 @@ class DefaultFetch
     /** Registers statistics. */
     void regStats();
 
+    /** Registers probes. */
+    void regProbePoints();
+
     /** Sets the main backwards communication time buffer pointer. */
     void setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer);
 
index b121ba70733877f9860481ab0c7bcbf90e3dcbc1..5b04c2a253b49d549226a030a001b8041f0b719a 100644 (file)
@@ -161,6 +161,13 @@ DefaultFetch<Impl>::name() const
     return cpu->name() + ".fetch";
 }
 
+template <class Impl>
+void
+DefaultFetch<Impl>::regProbePoints()
+{
+    ppFetch = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Fetch");
+}
+
 template <class Impl>
 void
 DefaultFetch<Impl>::regStats()
@@ -401,6 +408,7 @@ DefaultFetch<Impl>::processCacheCompletion(PacketPtr pkt)
     }
 
     pkt->req->setAccessLatency();
+    cpu->ppInstAccessComplete->notify(pkt);
     // Reset the mem req to NULL.
     delete pkt->req;
     delete pkt;
@@ -666,7 +674,6 @@ DefaultFetch<Impl>::finishTranslation(Fault fault, RequestPtr mem_req)
             DPRINTF(Fetch, "[tid:%i]: Doing Icache access.\n", tid);
             DPRINTF(Activity, "[tid:%i]: Activity: Waiting on I-cache "
                     "response.\n", tid);
-
             lastIcacheStall[tid] = curTick();
             fetchStatus[tid] = IcacheWaitResponse;
         }
@@ -1312,6 +1319,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
                 buildInst(tid, staticInst, curMacroop,
                           thisPC, nextPC, true);
 
+            ppFetch->notify(instruction);
             numInst++;
 
 #if TRACING_ON
index 1213cf12b2a53df9c5fe8d7d63943ad6abe048ce..24412e11f622f2e70323dd9bff23b2f3aab8554a 100644 (file)
@@ -52,6 +52,7 @@
 #include "cpu/o3/scoreboard.hh"
 #include "cpu/timebuf.hh"
 #include "debug/IEW.hh"
+#include "sim/probe/probe.hh"
 
 struct DerivO3CPUParams;
 class FUPool;
@@ -122,6 +123,10 @@ class DefaultIEW
     /** Writeback status. */
     StageStatus wbStatus;
 
+    /** Probe points. */
+    ProbePointArg<DynInstPtr> *ppMispredict;
+    ProbePointArg<DynInstPtr> *ppDispatch;
+
   public:
     /** Constructs a DefaultIEW with the given parameters. */
     DefaultIEW(O3CPU *_cpu, DerivO3CPUParams *params);
@@ -132,6 +137,9 @@ class DefaultIEW
     /** Registers statistics. */
     void regStats();
 
+    /** Registers probes. */
+    void regProbePoints();
+
     /** Initializes stage; sends back the number of free IQ and LSQ entries. */
     void startupStage();
 
index 6c5c57fb7f173756c035a11807baa74ff4d9981d..9cfbb3cfc8c70913a304f70d918ad81051935021 100644 (file)
@@ -111,6 +111,14 @@ DefaultIEW<Impl>::name() const
     return cpu->name() + ".iew";
 }
 
+template <class Impl>
+void
+DefaultIEW<Impl>::regProbePoints()
+{
+    ppDispatch = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Dispatch");
+    ppMispredict = new ProbePointArg<DynInstPtr>(cpu->getProbeManager(), "Mispredict");
+}
+
 template <class Impl>
 void
 DefaultIEW<Impl>::regStats()
@@ -1158,6 +1166,7 @@ DefaultIEW<Impl>::dispatchInsts(ThreadID tid)
 #if TRACING_ON
         inst->dispatchTick = curTick() - inst->fetchTick;
 #endif
+        ppDispatch->notify(inst);
     }
 
     if (!insts_to_dispatch.empty()) {
@@ -1357,6 +1366,8 @@ DefaultIEW<Impl>::executeInsts()
                 // If incorrect, then signal the ROB that it must be squashed.
                 squashDueToBranch(inst, tid);
 
+                ppMispredict->notify(inst);
+
                 if (inst->readPredTaken()) {
                     predictedTakenIncorrect++;
                 } else {
index ade0769951fc1382ab5ed26c12e14e3ff0573f53..277fe48d27b1a91608edc90509ce7ad0453b8393 100644 (file)
@@ -131,6 +131,8 @@ LSQUnit<Impl>::completeDataAccess(PacketPtr pkt)
     }
 
     pkt->req->setAccessLatency();
+    cpu->ppDataAccessComplete->notify(std::make_pair(inst, pkt));
+
     delete state;
     delete pkt->req;
     delete pkt;
diff --git a/src/cpu/o3/probe/SConscript b/src/cpu/o3/probe/SConscript
new file mode 100644 (file)
index 0000000..c8ab2b5
--- /dev/null
@@ -0,0 +1,45 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2013 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: Matt Horsnell
+
+Import('*')
+
+if 'O3CPU' in env['CPU_MODELS']:
+    SimObject('SimpleTrace.py')
+    Source('simple_trace.cc')
+    DebugFlag('SimpleTrace')
diff --git a/src/cpu/o3/probe/SimpleTrace.py b/src/cpu/o3/probe/SimpleTrace.py
new file mode 100644 (file)
index 0000000..eeec58e
--- /dev/null
@@ -0,0 +1,42 @@
+# Copyright (c) 2013 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: Matt Horsnell
+
+from Probe import *
+
+class SimpleTrace(ProbeListenerObject):
+    type = 'SimpleTrace'
+    cxx_header = 'cpu/o3/probe/simple_trace.hh'
diff --git a/src/cpu/o3/probe/simple_trace.cc b/src/cpu/o3/probe/simple_trace.cc
new file mode 100644 (file)
index 0000000..35d1365
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2013 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: Matt Horsnell
+ */
+
+#include "base/trace.hh"
+#include "cpu/o3/probe/simple_trace.hh"
+#include "debug/SimpleTrace.hh"
+
+void SimpleTrace::traceCommit(const O3CPUImpl::DynInstPtr &dynInst)
+{
+    DPRINTFR(SimpleTrace, "[%s]: Commit 0x%08x %s.\n", name(),
+             dynInst->instAddr(),
+             dynInst->staticInst->disassemble(dynInst->instAddr()));
+}
+
+void SimpleTrace::traceFetch(const O3CPUImpl::DynInstPtr &dynInst)
+{
+    DPRINTFR(SimpleTrace, "[%s]: Fetch 0x%08x %s.\n", name(),
+             dynInst->instAddr(),
+             dynInst->staticInst->disassemble(dynInst->instAddr()));
+}
+
+void SimpleTrace::regProbeListeners()
+{
+    typedef ProbeListenerArg<SimpleTrace, O3CPUImpl::DynInstPtr> DynInstListener;
+    listeners.push_back(new DynInstListener(this, "Commit", &SimpleTrace::traceCommit));
+    listeners.push_back(new DynInstListener(this, "Fetch", &SimpleTrace::traceFetch));
+}
+
+SimpleTrace*
+SimpleTraceParams::create()
+{
+    return new SimpleTrace(this);
+}
diff --git a/src/cpu/o3/probe/simple_trace.hh b/src/cpu/o3/probe/simple_trace.hh
new file mode 100644 (file)
index 0000000..6631288
--- /dev/null
@@ -0,0 +1,73 @@
+ /*
+ * Copyright (c) 2013 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: Matt Horsnell
+ */
+
+/**
+ * @file This file initializes a simple trace unit which listens to
+ * a probe point in the fetch and commit stage of the O3 pipeline
+ * and simply outputs those events as a dissassembled instruction stream
+ * to the trace output.
+ */
+#ifndef __CPU_O3_PROBE_SIMPLE_TRACE_HH__
+#define __CPU_O3_PROBE_SIMPLE_TRACE_HH__
+
+#include "cpu/o3/dyn_inst.hh"
+#include "cpu/o3/impl.hh"
+#include "params/SimpleTrace.hh"
+#include "sim/probe/probe.hh"
+
+class SimpleTrace : public ProbeListenerObject {
+
+  public:
+    SimpleTrace(const SimpleTraceParams *params):
+        ProbeListenerObject(params)
+    {
+    }
+
+    /** Register the probe listeners. */
+    void regProbeListeners();
+
+    /** Returns the name of the trace. */
+    const std::string name() const { return ProbeListenerObject::name() + ".trace"; }
+
+  private:
+    void traceFetch(const O3CPUImpl::DynInstPtr &dynInst);
+    void traceCommit(const O3CPUImpl::DynInstPtr &dynInst);
+
+};
+#endif//__CPU_O3_PROBE_SIMPLE_TRACE_HH__
index fc5416cbfb2a7355a0f94f76e97bd01b88e04b24..30c96838079d9ce4fe5a392656bdbdc8e84d4744 100644 (file)
@@ -616,6 +616,8 @@ class SimObject(object):
     void initState();
     void regStats();
     void resetStats();
+    void regProbePoints();
+    void regProbeListeners();
     void startup();
 ''')
 
index 7d443b1db3b031a9abc4174c74ed1a3abe4a3a7f..8529a74727f8e542ba0aa50a498c22d1dd888f40 100644 (file)
@@ -118,6 +118,12 @@ def instantiate(ckpt_dir=None):
     # Do a third pass to initialize statistics
     for obj in root.descendants(): obj.regStats()
 
+    # Do a fourth pass to initialize probe points
+    for obj in root.descendants(): obj.regProbePoints()
+
+    # Do a fifth pass to connect probe listeners
+    for obj in root.descendants(): obj.regProbeListeners()
+
     # We're done registering statistics.  Enable the stats package now.
     stats.enable()
 
diff --git a/src/sim/probe/Probe.py b/src/sim/probe/Probe.py
new file mode 100644 (file)
index 0000000..0a66251
--- /dev/null
@@ -0,0 +1,47 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2013 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: Matt Horsnell
+
+from m5.SimObject import SimObject
+from m5.params import *
+from m5.proxy import *
+
+class ProbeListenerObject(SimObject):
+    type = 'ProbeListenerObject'
+    cxx_header = 'sim/probe/probe.hh'
+    manager = Param.SimObject(Parent.any, "ProbeManager")
diff --git a/src/sim/probe/SConscript b/src/sim/probe/SConscript
new file mode 100644 (file)
index 0000000..a5a7a8b
--- /dev/null
@@ -0,0 +1,44 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2013 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: Matt Horsnell
+
+Import('*')
+
+SimObject('Probe.py')
+Source('probe.cc')
+DebugFlag('ProbeVerbose')
\ No newline at end of file
diff --git a/src/sim/probe/probe.cc b/src/sim/probe/probe.cc
new file mode 100644 (file)
index 0000000..6f1a3d5
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2013 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: Matt Horsnell
+ */
+
+#include "debug/ProbeVerbose.hh"
+#include "sim/probe/probe.hh"
+
+ProbePoint::ProbePoint(ProbeManager *manager, const std::string& _name)
+    : name(_name)
+{
+    if (manager) {
+        manager->addPoint(*this);
+    }
+}
+
+ProbeListenerObject::ProbeListenerObject(const ProbeListenerObjectParams *params)
+    : SimObject(params),
+      manager(params->manager->getProbeManager())
+{
+}
+
+ProbeListenerObject::~ProbeListenerObject()
+{
+    for (auto l = listeners.begin(); l != listeners.end(); ++l) {
+        delete (*l);
+    }
+    listeners.clear();
+}
+
+ProbeListener::ProbeListener(ProbeManager *manager, const std::string &name)
+{
+    manager->addListener(name, *this);
+}
+
+ProbeListenerObject*
+ProbeListenerObjectParams::create()
+{
+    return new ProbeListenerObject(this);
+}
+
+bool
+ProbeManager::addListener(std::string pointName, ProbeListener &listener)
+{
+    DPRINTFR(ProbeVerbose, "Probes: Call to addListener to \"%s\" on %s.\n", pointName, object->name());
+    bool added = false;
+    for (auto p = points.begin(); p != points.end(); ++p) {
+        if ((*p)->getName() == pointName) {
+            (*p)->addListener(&listener);
+            added = true;
+        }
+    }
+    if (!added) {
+        DPRINTFR(ProbeVerbose, "Probes: Call to addListener to \"%s\" on %s failed, no such point.\n", pointName, object->name());
+    }
+    return added;
+}
+
+bool
+ProbeManager::removeListener(std::string pointName, ProbeListener &listener)
+{
+    DPRINTFR(ProbeVerbose, "Probes: Call to removeListener from \"%s\" on %s.\n", pointName, object->name());
+    bool removed = false;
+    for (auto p = points.begin(); p != points.end(); ++p) {
+        if ((*p)->getName() == pointName) {
+            (*p)->removeListener(&listener);
+            removed = true;
+        }
+    }
+    if (!removed) {
+        DPRINTFR(ProbeVerbose, "Probes: Call to removeListener from \"%s\" on %s failed, no such point.\n", pointName, object->name());
+    }
+    return removed;
+}
+
+void
+ProbeManager::addPoint(ProbePoint &point)
+{
+    DPRINTFR(ProbeVerbose, "Probes: Call to addPoint \"%s\" to %s.\n", point.getName(), object->name());
+
+    for (auto p = points.begin(); p != points.end(); ++p) {
+        if ((*p)->getName() == point.getName()) {
+            DPRINTFR(ProbeVerbose, "Probes: Call to addPoint \"%s\" to %s failed, already added.\n", point.getName(), object->name());
+            return;
+        }
+    }
+    points.push_back(&point);
+}
diff --git a/src/sim/probe/probe.hh b/src/sim/probe/probe.hh
new file mode 100644 (file)
index 0000000..0f77ccb
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2013 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: Matt Horsnell
+  */
+
+/**
+ * @file This file describes the base components used for the probe system.
+ * There are currently 3 components:
+ *
+ * ProbePoint:          an event probe point i.e. send a notify from the point
+ *                      at which an instruction was committed.
+ *
+ * ProbeListener:       a listener provide a notify method that is called when
+ *                      a probe point event occurs. Multiple ProbeListeners
+ *                      can be added to each ProbePoint.
+ *
+ * ProbeListenerObject: a wrapper around a SimObject that can connect to another
+ *                      SimObject on which is will add ProbeListeners.
+ *
+ * ProbeManager:        used to match up ProbeListeners and ProbePoints.
+ *                      At <b>simulation init</b> this is handled by regProbePoints
+ *                      followed by regProbeListeners being called on each
+ *                      SimObject in hierarchical ordering.
+ *                      ProbeListeners can be added/removed dynamically at runtime.
+ */
+
+#ifndef __SIM_PROBE_PROBE_HH__
+#define __SIM_PROBE_PROBE_HH__
+
+#include <string>
+#include <vector>
+
+#include "base/trace.hh"
+#include "params/ProbeListenerObject.hh"
+#include "sim/sim_object.hh"
+
+/** Forward declare the ProbeManager. */
+class ProbeManager;
+class ProbeListener;
+
+/**
+ * This class is a minimal wrapper around SimObject. It is used to declare
+ * a python derived object that can be added as a ProbeListener to any other
+ * 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();
+    ProbeManager* getProbeManager() { return manager; }
+};
+
+/**
+ * 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.
+ */
+class ProbeListener
+{
+  public:
+    ProbeListener(ProbeManager *manager, const std::string &name);
+    virtual ~ProbeListener() {}
+};
+
+/**
+ * ProbeListener base class; again used to simplify use of ProbePoints
+ * in containers and used as to define interface for adding removing
+ * listeners to the ProbePoint.
+ */
+class ProbePoint
+{
+  protected:
+    const std::string name;
+  public:
+    ProbePoint(ProbeManager *manager, const std::string &name);
+    virtual ~ProbePoint() {}
+
+    virtual void addListener(ProbeListener *listener) = 0;
+    virtual void removeListener(ProbeListener *listener) = 0;
+    std::string getName() const { return name; }
+};
+
+/**
+ * ProbeManager is a conduit class that lives on each SimObject,
+ *  and is used to match up probe listeners with probe points.
+ */
+class ProbeManager
+{
+  private:
+    /** Required for sensible debug messages.*/
+    const SimObject *object;
+    /** Vector for name look-up. */
+    std::vector<ProbePoint *> points;
+
+  public:
+    ProbeManager(SimObject *obj)
+        : object(obj)
+    {}
+    virtual ~ProbeManager() {}
+
+    /**
+     * @brief Add a ProbeListener to the ProbePoint named by pointName.
+     *        If the name doesn't resolve a ProbePoint return false.
+     * @param pointName the name of the ProbePoint to add the ProbeListener to.
+     * @param listener the ProbeListener to add.
+     * @return true if added, false otherwise.
+     */
+    bool addListener(std::string pointName, ProbeListener &listener);
+
+    /**
+     * @brief Remove a ProbeListener from the ProbePoint named by pointName.
+     *        If the name doesn't resolve a ProbePoint return false.
+     * @param pointName the name of the ProbePoint to remove the ProbeListener
+     *        from.
+     * @param listener the ProbeListener to remove.
+     * @return true if removed, false otherwise.
+     */
+    bool removeListener(std::string pointName, ProbeListener &listener);
+
+    /**
+     * @brief Add a ProbePoint to this SimObject ProbeManager.
+     * @param point the ProbePoint to add.
+     */
+    void addPoint(ProbePoint &point);
+};
+
+/**
+ * ProbeListenerArgBase is used to define the base interface to a
+ * ProbeListenerArg (i.e the notify method on specific type).
+ *
+ * It is necessary to split this out from ProbeListenerArg, as that
+ * templates off the class containing the function that notify calls.
+ */
+template <class Arg>
+class ProbeListenerArgBase : public ProbeListener
+{
+  public:
+    ProbeListenerArgBase(ProbeManager *pm, const std::string &name)
+        : ProbeListener(pm, name)
+    {}
+    virtual void notify(const Arg &val) = 0;
+};
+
+/**
+ * ProbeListenerArg generates a listener for the class of Arg and the
+ * class type T which is the class containing the function that notify will
+ * call.
+ *
+ * Note that the function is passed as a pointer on construction.
+ */
+template <class T, class Arg>
+class ProbeListenerArg : public ProbeListenerArgBase<Arg>
+{
+  private:
+    T *object;
+    void (T::* function)(const Arg &);
+
+  public:
+    /**
+     * @param obj the class of type Tcontaining the method to call on notify.
+     * @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),
+          object(obj),
+          function(func)
+    {}
+
+    /**
+     * @brief called when the ProbePoint calls notify. This is a shim through to
+     *        the function passed during construction.
+     * @param val the argument value to pass.
+     */
+    virtual void notify(const Arg &val) { (object->*function)(val); }
+};
+
+/**
+ * ProbePointArg generates a point for the class of Arg. As ProbePointArgs talk
+ * directly to ProbeListenerArgs of the same type, we can store the vector of
+ * ProbeListeners as their Arg type (and not as base type).
+ *
+ * Methods are provided to addListener, removeListener and notify.
+ */
+template <typename Arg>
+class ProbePointArg : public ProbePoint
+{
+    /** The attached listeners. */
+    std::vector<ProbeListenerArgBase<Arg> *> listeners;
+
+  public:
+    ProbePointArg(ProbeManager *manager, std::string name)
+        : ProbePoint(manager, name)
+    {
+    }
+
+    /**
+     * @brief adds a ProbeListener to this ProbePoints notify list.
+     * @param l the ProbeListener to add to the notify list.
+     */
+    void addListener(ProbeListener *l)
+    {
+        // check listener not already added
+        if (std::find(listeners.begin(), listeners.end(), l) == listeners.end()) {
+            listeners.push_back(static_cast<ProbeListenerArgBase<Arg> *>(l));
+        }
+    }
+
+    /**
+     * @brief remove a ProbeListener from this ProbePoints notify list.
+     * @param l the ProbeListener to remove from the notify list.
+     */
+    void removeListener(ProbeListener *l)
+    {
+        listeners.erase(std::remove(listeners.begin(), listeners.end(), l),
+                        listeners.end());
+    }
+
+    /**
+     * @brief called at the ProbePoint call site, passes arg to each listener.
+     * @param arg the argument to pass to each listener.
+     */
+    void notify(const Arg &arg)
+    {
+        for (auto l = listeners.begin(); l != listeners.end(); ++l) {
+            (*l)->notify(arg);
+        }
+    }
+};
+#endif//__SIM_PROBE_PROBE_HH__
index 0edad719e0a8a5eac084a34721038eb056a0c1a1..44d498c3c2c8ee131e447cc254a36047abeb6f32 100644 (file)
@@ -39,6 +39,7 @@
 #include "base/trace.hh"
 #include "base/types.hh"
 #include "debug/Checkpoint.hh"
+#include "sim/probe/probe.hh"
 #include "sim/sim_object.hh"
 #include "sim/stats.hh"
 
@@ -65,8 +66,8 @@ SimObject::SimObject(const Params *p)
 #ifdef DEBUG
     doDebugBreak = false;
 #endif
-
     simObjectList.push_back(this);
+    probeManager = new ProbeManager(this);
 }
 
 void
@@ -108,6 +109,28 @@ SimObject::resetStats()
 {
 }
 
+/**
+ * No probe points by default, so do nothing in base.
+ */
+void
+SimObject::regProbePoints()
+{
+}
+
+/**
+ * No probe listeners by default, so do nothing in base.
+ */
+void
+SimObject::regProbeListeners()
+{
+}
+
+ProbeManager *
+SimObject::getProbeManager()
+{
+    return probeManager;
+}
+
 //
 // static function: serialize all SimObjects.
 //
index 1cb06d777d6fbb7f65fdc686003fbb59618da58f..e4526e7738f07af643f74cbc265fef9311ba93cc 100644 (file)
@@ -51,7 +51,7 @@
 
 class BaseCPU;
 class Event;
-
+class ProbeManager;
 /**
  * Abstract superclass for simulation objects.  Represents things that
  * correspond to physical components and can be specified via the
@@ -90,6 +90,9 @@ class SimObject : public EventManager, public Serializable, public Drainable
     /** List of all instantiated simulation objects. */
     static SimObjectList simObjectList;
 
+    /** Manager coordinates hooking up probe points with listeners. */
+    ProbeManager *probeManager;
+
   protected:
     /** Cached copy of the object parameters. */
     const SimObjectParams *_params;
@@ -142,6 +145,21 @@ class SimObject : public EventManager, public Serializable, public Drainable
      */
     virtual void resetStats();
 
+    /**
+     * Register probe points for this object.
+     */
+    virtual void regProbePoints();
+
+    /**
+     * Register probe listeners for this object.
+     */
+    virtual void regProbeListeners();
+
+    /**
+     * Get the probe manager for this object.
+     */
+    ProbeManager *getProbeManager();
+
     /**
      * startup() is the final initialization call before simulation.
      * All state is initialized (including unserialized state, if any,