probe.hh revision 10460
110023Smatt.horsnell@ARM.com/*
210023Smatt.horsnell@ARM.com * Copyright (c) 2013 ARM Limited
310023Smatt.horsnell@ARM.com * All rights reserved
410023Smatt.horsnell@ARM.com *
510023Smatt.horsnell@ARM.com * The license below extends only to copyright in the software and shall
610023Smatt.horsnell@ARM.com * not be construed as granting a license to any other intellectual
710023Smatt.horsnell@ARM.com * property including but not limited to intellectual property relating
810023Smatt.horsnell@ARM.com * to a hardware implementation of the functionality of the software
910023Smatt.horsnell@ARM.com * licensed hereunder.  You may use the software subject to the license
1010023Smatt.horsnell@ARM.com * terms below provided that you ensure that this notice is replicated
1110023Smatt.horsnell@ARM.com * unmodified and in its entirety in all distributions of the software,
1210023Smatt.horsnell@ARM.com * modified or unmodified, in source code or in binary form.
1310023Smatt.horsnell@ARM.com *
1410023Smatt.horsnell@ARM.com * Redistribution and use in source and binary forms, with or without
1510023Smatt.horsnell@ARM.com * modification, are permitted provided that the following conditions are
1610023Smatt.horsnell@ARM.com * met: redistributions of source code must retain the above copyright
1710023Smatt.horsnell@ARM.com * notice, this list of conditions and the following disclaimer;
1810023Smatt.horsnell@ARM.com * redistributions in binary form must reproduce the above copyright
1910023Smatt.horsnell@ARM.com * notice, this list of conditions and the following disclaimer in the
2010023Smatt.horsnell@ARM.com * documentation and/or other materials provided with the distribution;
2110023Smatt.horsnell@ARM.com * neither the name of the copyright holders nor the names of its
2210023Smatt.horsnell@ARM.com * contributors may be used to endorse or promote products derived from
2310023Smatt.horsnell@ARM.com * this software without specific prior written permission.
2410023Smatt.horsnell@ARM.com *
2510023Smatt.horsnell@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610023Smatt.horsnell@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710023Smatt.horsnell@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810023Smatt.horsnell@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910023Smatt.horsnell@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010023Smatt.horsnell@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110023Smatt.horsnell@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210023Smatt.horsnell@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310023Smatt.horsnell@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410023Smatt.horsnell@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510023Smatt.horsnell@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610023Smatt.horsnell@ARM.com *
3710023Smatt.horsnell@ARM.com * Authors: Matt Horsnell
3810023Smatt.horsnell@ARM.com  */
3910023Smatt.horsnell@ARM.com
4010023Smatt.horsnell@ARM.com/**
4110023Smatt.horsnell@ARM.com * @file This file describes the base components used for the probe system.
4210023Smatt.horsnell@ARM.com * There are currently 3 components:
4310023Smatt.horsnell@ARM.com *
4410023Smatt.horsnell@ARM.com * ProbePoint:          an event probe point i.e. send a notify from the point
4510023Smatt.horsnell@ARM.com *                      at which an instruction was committed.
4610023Smatt.horsnell@ARM.com *
4710023Smatt.horsnell@ARM.com * ProbeListener:       a listener provide a notify method that is called when
4810023Smatt.horsnell@ARM.com *                      a probe point event occurs. Multiple ProbeListeners
4910023Smatt.horsnell@ARM.com *                      can be added to each ProbePoint.
5010023Smatt.horsnell@ARM.com *
5110023Smatt.horsnell@ARM.com * ProbeListenerObject: a wrapper around a SimObject that can connect to another
5210023Smatt.horsnell@ARM.com *                      SimObject on which is will add ProbeListeners.
5310023Smatt.horsnell@ARM.com *
5410023Smatt.horsnell@ARM.com * ProbeManager:        used to match up ProbeListeners and ProbePoints.
5510023Smatt.horsnell@ARM.com *                      At <b>simulation init</b> this is handled by regProbePoints
5610023Smatt.horsnell@ARM.com *                      followed by regProbeListeners being called on each
5710023Smatt.horsnell@ARM.com *                      SimObject in hierarchical ordering.
5810023Smatt.horsnell@ARM.com *                      ProbeListeners can be added/removed dynamically at runtime.
5910023Smatt.horsnell@ARM.com */
6010023Smatt.horsnell@ARM.com
6110023Smatt.horsnell@ARM.com#ifndef __SIM_PROBE_PROBE_HH__
6210023Smatt.horsnell@ARM.com#define __SIM_PROBE_PROBE_HH__
6310023Smatt.horsnell@ARM.com
6410023Smatt.horsnell@ARM.com#include <string>
6510023Smatt.horsnell@ARM.com#include <vector>
6610023Smatt.horsnell@ARM.com
6710023Smatt.horsnell@ARM.com#include "base/trace.hh"
6810023Smatt.horsnell@ARM.com#include "params/ProbeListenerObject.hh"
6910023Smatt.horsnell@ARM.com#include "sim/sim_object.hh"
7010023Smatt.horsnell@ARM.com
7110023Smatt.horsnell@ARM.com/** Forward declare the ProbeManager. */
7210023Smatt.horsnell@ARM.comclass ProbeManager;
7310023Smatt.horsnell@ARM.comclass ProbeListener;
7410023Smatt.horsnell@ARM.com
7510023Smatt.horsnell@ARM.com/**
7610460SAndreas.Sandberg@ARM.com * Name space containing shared probe point declarations.
7710460SAndreas.Sandberg@ARM.com *
7810460SAndreas.Sandberg@ARM.com * Probe types that are shared between multiple types of SimObjects
7910460SAndreas.Sandberg@ARM.com * should live in this name space. This makes it possible to use a
8010460SAndreas.Sandberg@ARM.com * common instrumentation interface for devices such as PMUs that have
8110460SAndreas.Sandberg@ARM.com * different implementations in different ISAs.
8210460SAndreas.Sandberg@ARM.com */
8310460SAndreas.Sandberg@ARM.comnamespace ProbePoints {
8410460SAndreas.Sandberg@ARM.com/* Note: This is only here for documentation purposes, new probe
8510460SAndreas.Sandberg@ARM.com * points should normally be declared in their own header files. See
8610460SAndreas.Sandberg@ARM.com * for example pmu.hh.
8710460SAndreas.Sandberg@ARM.com */
8810460SAndreas.Sandberg@ARM.com}
8910460SAndreas.Sandberg@ARM.com
9010460SAndreas.Sandberg@ARM.com/**
9110023Smatt.horsnell@ARM.com * This class is a minimal wrapper around SimObject. It is used to declare
9210023Smatt.horsnell@ARM.com * a python derived object that can be added as a ProbeListener to any other
9310023Smatt.horsnell@ARM.com * SimObject.
9410023Smatt.horsnell@ARM.com *
9510023Smatt.horsnell@ARM.com * It instantiates manager from a call to Parent.any.
9610023Smatt.horsnell@ARM.com * The vector of listeners is used simply to hold onto listeners until the
9710023Smatt.horsnell@ARM.com * ProbeListenerObject is destroyed.
9810023Smatt.horsnell@ARM.com */
9910023Smatt.horsnell@ARM.comclass ProbeListenerObject : public SimObject
10010023Smatt.horsnell@ARM.com{
10110023Smatt.horsnell@ARM.com  protected:
10210023Smatt.horsnell@ARM.com    ProbeManager *manager;
10310023Smatt.horsnell@ARM.com    std::vector<ProbeListener *> listeners;
10410023Smatt.horsnell@ARM.com
10510023Smatt.horsnell@ARM.com  public:
10610023Smatt.horsnell@ARM.com    ProbeListenerObject(const ProbeListenerObjectParams *params);
10710023Smatt.horsnell@ARM.com    virtual ~ProbeListenerObject();
10810023Smatt.horsnell@ARM.com    ProbeManager* getProbeManager() { return manager; }
10910023Smatt.horsnell@ARM.com};
11010023Smatt.horsnell@ARM.com
11110023Smatt.horsnell@ARM.com/**
11210023Smatt.horsnell@ARM.com * ProbeListener base class; here to simplify things like containers
11310023Smatt.horsnell@ARM.com * containing multiple types of ProbeListener.
11410023Smatt.horsnell@ARM.com *
11510023Smatt.horsnell@ARM.com * Note a ProbeListener is added to the ProbePoint in constructor by
11610023Smatt.horsnell@ARM.com * using the ProbeManager passed in.
11710023Smatt.horsnell@ARM.com */
11810023Smatt.horsnell@ARM.comclass ProbeListener
11910023Smatt.horsnell@ARM.com{
12010023Smatt.horsnell@ARM.com  public:
12110023Smatt.horsnell@ARM.com    ProbeListener(ProbeManager *manager, const std::string &name);
12210365SAndreas.Sandberg@ARM.com    virtual ~ProbeListener();
12310365SAndreas.Sandberg@ARM.com
12410365SAndreas.Sandberg@ARM.com  protected:
12510365SAndreas.Sandberg@ARM.com    ProbeManager *const manager;
12610365SAndreas.Sandberg@ARM.com    const std::string name;
12710023Smatt.horsnell@ARM.com};
12810023Smatt.horsnell@ARM.com
12910023Smatt.horsnell@ARM.com/**
13010023Smatt.horsnell@ARM.com * ProbeListener base class; again used to simplify use of ProbePoints
13110023Smatt.horsnell@ARM.com * in containers and used as to define interface for adding removing
13210023Smatt.horsnell@ARM.com * listeners to the ProbePoint.
13310023Smatt.horsnell@ARM.com */
13410023Smatt.horsnell@ARM.comclass ProbePoint
13510023Smatt.horsnell@ARM.com{
13610023Smatt.horsnell@ARM.com  protected:
13710023Smatt.horsnell@ARM.com    const std::string name;
13810023Smatt.horsnell@ARM.com  public:
13910023Smatt.horsnell@ARM.com    ProbePoint(ProbeManager *manager, const std::string &name);
14010023Smatt.horsnell@ARM.com    virtual ~ProbePoint() {}
14110023Smatt.horsnell@ARM.com
14210023Smatt.horsnell@ARM.com    virtual void addListener(ProbeListener *listener) = 0;
14310023Smatt.horsnell@ARM.com    virtual void removeListener(ProbeListener *listener) = 0;
14410023Smatt.horsnell@ARM.com    std::string getName() const { return name; }
14510023Smatt.horsnell@ARM.com};
14610023Smatt.horsnell@ARM.com
14710023Smatt.horsnell@ARM.com/**
14810023Smatt.horsnell@ARM.com * ProbeManager is a conduit class that lives on each SimObject,
14910023Smatt.horsnell@ARM.com *  and is used to match up probe listeners with probe points.
15010023Smatt.horsnell@ARM.com */
15110023Smatt.horsnell@ARM.comclass ProbeManager
15210023Smatt.horsnell@ARM.com{
15310023Smatt.horsnell@ARM.com  private:
15410023Smatt.horsnell@ARM.com    /** Required for sensible debug messages.*/
15510104Smitch.hayenga@arm.com    const M5_CLASS_VAR_USED SimObject *object;
15610023Smatt.horsnell@ARM.com    /** Vector for name look-up. */
15710023Smatt.horsnell@ARM.com    std::vector<ProbePoint *> points;
15810023Smatt.horsnell@ARM.com
15910023Smatt.horsnell@ARM.com  public:
16010023Smatt.horsnell@ARM.com    ProbeManager(SimObject *obj)
16110023Smatt.horsnell@ARM.com        : object(obj)
16210023Smatt.horsnell@ARM.com    {}
16310023Smatt.horsnell@ARM.com    virtual ~ProbeManager() {}
16410023Smatt.horsnell@ARM.com
16510023Smatt.horsnell@ARM.com    /**
16610023Smatt.horsnell@ARM.com     * @brief Add a ProbeListener to the ProbePoint named by pointName.
16710023Smatt.horsnell@ARM.com     *        If the name doesn't resolve a ProbePoint return false.
16810023Smatt.horsnell@ARM.com     * @param pointName the name of the ProbePoint to add the ProbeListener to.
16910023Smatt.horsnell@ARM.com     * @param listener the ProbeListener to add.
17010023Smatt.horsnell@ARM.com     * @return true if added, false otherwise.
17110023Smatt.horsnell@ARM.com     */
17210023Smatt.horsnell@ARM.com    bool addListener(std::string pointName, ProbeListener &listener);
17310023Smatt.horsnell@ARM.com
17410023Smatt.horsnell@ARM.com    /**
17510023Smatt.horsnell@ARM.com     * @brief Remove a ProbeListener from the ProbePoint named by pointName.
17610023Smatt.horsnell@ARM.com     *        If the name doesn't resolve a ProbePoint return false.
17710023Smatt.horsnell@ARM.com     * @param pointName the name of the ProbePoint to remove the ProbeListener
17810023Smatt.horsnell@ARM.com     *        from.
17910023Smatt.horsnell@ARM.com     * @param listener the ProbeListener to remove.
18010023Smatt.horsnell@ARM.com     * @return true if removed, false otherwise.
18110023Smatt.horsnell@ARM.com     */
18210023Smatt.horsnell@ARM.com    bool removeListener(std::string pointName, ProbeListener &listener);
18310023Smatt.horsnell@ARM.com
18410023Smatt.horsnell@ARM.com    /**
18510023Smatt.horsnell@ARM.com     * @brief Add a ProbePoint to this SimObject ProbeManager.
18610023Smatt.horsnell@ARM.com     * @param point the ProbePoint to add.
18710023Smatt.horsnell@ARM.com     */
18810023Smatt.horsnell@ARM.com    void addPoint(ProbePoint &point);
18910023Smatt.horsnell@ARM.com};
19010023Smatt.horsnell@ARM.com
19110023Smatt.horsnell@ARM.com/**
19210023Smatt.horsnell@ARM.com * ProbeListenerArgBase is used to define the base interface to a
19310023Smatt.horsnell@ARM.com * ProbeListenerArg (i.e the notify method on specific type).
19410023Smatt.horsnell@ARM.com *
19510023Smatt.horsnell@ARM.com * It is necessary to split this out from ProbeListenerArg, as that
19610023Smatt.horsnell@ARM.com * templates off the class containing the function that notify calls.
19710023Smatt.horsnell@ARM.com */
19810023Smatt.horsnell@ARM.comtemplate <class Arg>
19910023Smatt.horsnell@ARM.comclass ProbeListenerArgBase : public ProbeListener
20010023Smatt.horsnell@ARM.com{
20110023Smatt.horsnell@ARM.com  public:
20210023Smatt.horsnell@ARM.com    ProbeListenerArgBase(ProbeManager *pm, const std::string &name)
20310023Smatt.horsnell@ARM.com        : ProbeListener(pm, name)
20410023Smatt.horsnell@ARM.com    {}
20510023Smatt.horsnell@ARM.com    virtual void notify(const Arg &val) = 0;
20610023Smatt.horsnell@ARM.com};
20710023Smatt.horsnell@ARM.com
20810023Smatt.horsnell@ARM.com/**
20910023Smatt.horsnell@ARM.com * ProbeListenerArg generates a listener for the class of Arg and the
21010023Smatt.horsnell@ARM.com * class type T which is the class containing the function that notify will
21110023Smatt.horsnell@ARM.com * call.
21210023Smatt.horsnell@ARM.com *
21310023Smatt.horsnell@ARM.com * Note that the function is passed as a pointer on construction.
21410023Smatt.horsnell@ARM.com */
21510023Smatt.horsnell@ARM.comtemplate <class T, class Arg>
21610023Smatt.horsnell@ARM.comclass ProbeListenerArg : public ProbeListenerArgBase<Arg>
21710023Smatt.horsnell@ARM.com{
21810023Smatt.horsnell@ARM.com  private:
21910023Smatt.horsnell@ARM.com    T *object;
22010023Smatt.horsnell@ARM.com    void (T::* function)(const Arg &);
22110023Smatt.horsnell@ARM.com
22210023Smatt.horsnell@ARM.com  public:
22310023Smatt.horsnell@ARM.com    /**
22410023Smatt.horsnell@ARM.com     * @param obj the class of type Tcontaining the method to call on notify.
22510023Smatt.horsnell@ARM.com     * @param name the name of the ProbePoint to add this listener to.
22610023Smatt.horsnell@ARM.com     * @param func a pointer to the function on obj (called on notify).
22710023Smatt.horsnell@ARM.com     */
22810023Smatt.horsnell@ARM.com    ProbeListenerArg(T *obj, const std::string &name, void (T::* func)(const Arg &))
22910023Smatt.horsnell@ARM.com        : ProbeListenerArgBase<Arg>(obj->getProbeManager(), name),
23010023Smatt.horsnell@ARM.com          object(obj),
23110023Smatt.horsnell@ARM.com          function(func)
23210023Smatt.horsnell@ARM.com    {}
23310023Smatt.horsnell@ARM.com
23410023Smatt.horsnell@ARM.com    /**
23510023Smatt.horsnell@ARM.com     * @brief called when the ProbePoint calls notify. This is a shim through to
23610023Smatt.horsnell@ARM.com     *        the function passed during construction.
23710023Smatt.horsnell@ARM.com     * @param val the argument value to pass.
23810023Smatt.horsnell@ARM.com     */
23910023Smatt.horsnell@ARM.com    virtual void notify(const Arg &val) { (object->*function)(val); }
24010023Smatt.horsnell@ARM.com};
24110023Smatt.horsnell@ARM.com
24210023Smatt.horsnell@ARM.com/**
24310023Smatt.horsnell@ARM.com * ProbePointArg generates a point for the class of Arg. As ProbePointArgs talk
24410023Smatt.horsnell@ARM.com * directly to ProbeListenerArgs of the same type, we can store the vector of
24510023Smatt.horsnell@ARM.com * ProbeListeners as their Arg type (and not as base type).
24610023Smatt.horsnell@ARM.com *
24710023Smatt.horsnell@ARM.com * Methods are provided to addListener, removeListener and notify.
24810023Smatt.horsnell@ARM.com */
24910023Smatt.horsnell@ARM.comtemplate <typename Arg>
25010023Smatt.horsnell@ARM.comclass ProbePointArg : public ProbePoint
25110023Smatt.horsnell@ARM.com{
25210023Smatt.horsnell@ARM.com    /** The attached listeners. */
25310023Smatt.horsnell@ARM.com    std::vector<ProbeListenerArgBase<Arg> *> listeners;
25410023Smatt.horsnell@ARM.com
25510023Smatt.horsnell@ARM.com  public:
25610023Smatt.horsnell@ARM.com    ProbePointArg(ProbeManager *manager, std::string name)
25710023Smatt.horsnell@ARM.com        : ProbePoint(manager, name)
25810023Smatt.horsnell@ARM.com    {
25910023Smatt.horsnell@ARM.com    }
26010023Smatt.horsnell@ARM.com
26110023Smatt.horsnell@ARM.com    /**
26210023Smatt.horsnell@ARM.com     * @brief adds a ProbeListener to this ProbePoints notify list.
26310023Smatt.horsnell@ARM.com     * @param l the ProbeListener to add to the notify list.
26410023Smatt.horsnell@ARM.com     */
26510023Smatt.horsnell@ARM.com    void addListener(ProbeListener *l)
26610023Smatt.horsnell@ARM.com    {
26710023Smatt.horsnell@ARM.com        // check listener not already added
26810023Smatt.horsnell@ARM.com        if (std::find(listeners.begin(), listeners.end(), l) == listeners.end()) {
26910023Smatt.horsnell@ARM.com            listeners.push_back(static_cast<ProbeListenerArgBase<Arg> *>(l));
27010023Smatt.horsnell@ARM.com        }
27110023Smatt.horsnell@ARM.com    }
27210023Smatt.horsnell@ARM.com
27310023Smatt.horsnell@ARM.com    /**
27410023Smatt.horsnell@ARM.com     * @brief remove a ProbeListener from this ProbePoints notify list.
27510023Smatt.horsnell@ARM.com     * @param l the ProbeListener to remove from the notify list.
27610023Smatt.horsnell@ARM.com     */
27710023Smatt.horsnell@ARM.com    void removeListener(ProbeListener *l)
27810023Smatt.horsnell@ARM.com    {
27910023Smatt.horsnell@ARM.com        listeners.erase(std::remove(listeners.begin(), listeners.end(), l),
28010023Smatt.horsnell@ARM.com                        listeners.end());
28110023Smatt.horsnell@ARM.com    }
28210023Smatt.horsnell@ARM.com
28310023Smatt.horsnell@ARM.com    /**
28410023Smatt.horsnell@ARM.com     * @brief called at the ProbePoint call site, passes arg to each listener.
28510023Smatt.horsnell@ARM.com     * @param arg the argument to pass to each listener.
28610023Smatt.horsnell@ARM.com     */
28710023Smatt.horsnell@ARM.com    void notify(const Arg &arg)
28810023Smatt.horsnell@ARM.com    {
28910023Smatt.horsnell@ARM.com        for (auto l = listeners.begin(); l != listeners.end(); ++l) {
29010023Smatt.horsnell@ARM.com            (*l)->notify(arg);
29110023Smatt.horsnell@ARM.com        }
29210023Smatt.horsnell@ARM.com    }
29310023Smatt.horsnell@ARM.com};
29410023Smatt.horsnell@ARM.com#endif//__SIM_PROBE_PROBE_HH__
295