probe.hh revision 10365
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/**
7610023Smatt.horsnell@ARM.com * This class is a minimal wrapper around SimObject. It is used to declare
7710023Smatt.horsnell@ARM.com * a python derived object that can be added as a ProbeListener to any other
7810023Smatt.horsnell@ARM.com * SimObject.
7910023Smatt.horsnell@ARM.com *
8010023Smatt.horsnell@ARM.com * It instantiates manager from a call to Parent.any.
8110023Smatt.horsnell@ARM.com * The vector of listeners is used simply to hold onto listeners until the
8210023Smatt.horsnell@ARM.com * ProbeListenerObject is destroyed.
8310023Smatt.horsnell@ARM.com */
8410023Smatt.horsnell@ARM.comclass ProbeListenerObject : public SimObject
8510023Smatt.horsnell@ARM.com{
8610023Smatt.horsnell@ARM.com  protected:
8710023Smatt.horsnell@ARM.com    ProbeManager *manager;
8810023Smatt.horsnell@ARM.com    std::vector<ProbeListener *> listeners;
8910023Smatt.horsnell@ARM.com
9010023Smatt.horsnell@ARM.com  public:
9110023Smatt.horsnell@ARM.com    ProbeListenerObject(const ProbeListenerObjectParams *params);
9210023Smatt.horsnell@ARM.com    virtual ~ProbeListenerObject();
9310023Smatt.horsnell@ARM.com    ProbeManager* getProbeManager() { return manager; }
9410023Smatt.horsnell@ARM.com};
9510023Smatt.horsnell@ARM.com
9610023Smatt.horsnell@ARM.com/**
9710023Smatt.horsnell@ARM.com * ProbeListener base class; here to simplify things like containers
9810023Smatt.horsnell@ARM.com * containing multiple types of ProbeListener.
9910023Smatt.horsnell@ARM.com *
10010023Smatt.horsnell@ARM.com * Note a ProbeListener is added to the ProbePoint in constructor by
10110023Smatt.horsnell@ARM.com * using the ProbeManager passed in.
10210023Smatt.horsnell@ARM.com */
10310023Smatt.horsnell@ARM.comclass ProbeListener
10410023Smatt.horsnell@ARM.com{
10510023Smatt.horsnell@ARM.com  public:
10610023Smatt.horsnell@ARM.com    ProbeListener(ProbeManager *manager, const std::string &name);
10710365SAndreas.Sandberg@ARM.com    virtual ~ProbeListener();
10810365SAndreas.Sandberg@ARM.com
10910365SAndreas.Sandberg@ARM.com  protected:
11010365SAndreas.Sandberg@ARM.com    ProbeManager *const manager;
11110365SAndreas.Sandberg@ARM.com    const std::string name;
11210023Smatt.horsnell@ARM.com};
11310023Smatt.horsnell@ARM.com
11410023Smatt.horsnell@ARM.com/**
11510023Smatt.horsnell@ARM.com * ProbeListener base class; again used to simplify use of ProbePoints
11610023Smatt.horsnell@ARM.com * in containers and used as to define interface for adding removing
11710023Smatt.horsnell@ARM.com * listeners to the ProbePoint.
11810023Smatt.horsnell@ARM.com */
11910023Smatt.horsnell@ARM.comclass ProbePoint
12010023Smatt.horsnell@ARM.com{
12110023Smatt.horsnell@ARM.com  protected:
12210023Smatt.horsnell@ARM.com    const std::string name;
12310023Smatt.horsnell@ARM.com  public:
12410023Smatt.horsnell@ARM.com    ProbePoint(ProbeManager *manager, const std::string &name);
12510023Smatt.horsnell@ARM.com    virtual ~ProbePoint() {}
12610023Smatt.horsnell@ARM.com
12710023Smatt.horsnell@ARM.com    virtual void addListener(ProbeListener *listener) = 0;
12810023Smatt.horsnell@ARM.com    virtual void removeListener(ProbeListener *listener) = 0;
12910023Smatt.horsnell@ARM.com    std::string getName() const { return name; }
13010023Smatt.horsnell@ARM.com};
13110023Smatt.horsnell@ARM.com
13210023Smatt.horsnell@ARM.com/**
13310023Smatt.horsnell@ARM.com * ProbeManager is a conduit class that lives on each SimObject,
13410023Smatt.horsnell@ARM.com *  and is used to match up probe listeners with probe points.
13510023Smatt.horsnell@ARM.com */
13610023Smatt.horsnell@ARM.comclass ProbeManager
13710023Smatt.horsnell@ARM.com{
13810023Smatt.horsnell@ARM.com  private:
13910023Smatt.horsnell@ARM.com    /** Required for sensible debug messages.*/
14010104Smitch.hayenga@arm.com    const M5_CLASS_VAR_USED SimObject *object;
14110023Smatt.horsnell@ARM.com    /** Vector for name look-up. */
14210023Smatt.horsnell@ARM.com    std::vector<ProbePoint *> points;
14310023Smatt.horsnell@ARM.com
14410023Smatt.horsnell@ARM.com  public:
14510023Smatt.horsnell@ARM.com    ProbeManager(SimObject *obj)
14610023Smatt.horsnell@ARM.com        : object(obj)
14710023Smatt.horsnell@ARM.com    {}
14810023Smatt.horsnell@ARM.com    virtual ~ProbeManager() {}
14910023Smatt.horsnell@ARM.com
15010023Smatt.horsnell@ARM.com    /**
15110023Smatt.horsnell@ARM.com     * @brief Add a ProbeListener to the ProbePoint named by pointName.
15210023Smatt.horsnell@ARM.com     *        If the name doesn't resolve a ProbePoint return false.
15310023Smatt.horsnell@ARM.com     * @param pointName the name of the ProbePoint to add the ProbeListener to.
15410023Smatt.horsnell@ARM.com     * @param listener the ProbeListener to add.
15510023Smatt.horsnell@ARM.com     * @return true if added, false otherwise.
15610023Smatt.horsnell@ARM.com     */
15710023Smatt.horsnell@ARM.com    bool addListener(std::string pointName, ProbeListener &listener);
15810023Smatt.horsnell@ARM.com
15910023Smatt.horsnell@ARM.com    /**
16010023Smatt.horsnell@ARM.com     * @brief Remove a ProbeListener from the ProbePoint named by pointName.
16110023Smatt.horsnell@ARM.com     *        If the name doesn't resolve a ProbePoint return false.
16210023Smatt.horsnell@ARM.com     * @param pointName the name of the ProbePoint to remove the ProbeListener
16310023Smatt.horsnell@ARM.com     *        from.
16410023Smatt.horsnell@ARM.com     * @param listener the ProbeListener to remove.
16510023Smatt.horsnell@ARM.com     * @return true if removed, false otherwise.
16610023Smatt.horsnell@ARM.com     */
16710023Smatt.horsnell@ARM.com    bool removeListener(std::string pointName, ProbeListener &listener);
16810023Smatt.horsnell@ARM.com
16910023Smatt.horsnell@ARM.com    /**
17010023Smatt.horsnell@ARM.com     * @brief Add a ProbePoint to this SimObject ProbeManager.
17110023Smatt.horsnell@ARM.com     * @param point the ProbePoint to add.
17210023Smatt.horsnell@ARM.com     */
17310023Smatt.horsnell@ARM.com    void addPoint(ProbePoint &point);
17410023Smatt.horsnell@ARM.com};
17510023Smatt.horsnell@ARM.com
17610023Smatt.horsnell@ARM.com/**
17710023Smatt.horsnell@ARM.com * ProbeListenerArgBase is used to define the base interface to a
17810023Smatt.horsnell@ARM.com * ProbeListenerArg (i.e the notify method on specific type).
17910023Smatt.horsnell@ARM.com *
18010023Smatt.horsnell@ARM.com * It is necessary to split this out from ProbeListenerArg, as that
18110023Smatt.horsnell@ARM.com * templates off the class containing the function that notify calls.
18210023Smatt.horsnell@ARM.com */
18310023Smatt.horsnell@ARM.comtemplate <class Arg>
18410023Smatt.horsnell@ARM.comclass ProbeListenerArgBase : public ProbeListener
18510023Smatt.horsnell@ARM.com{
18610023Smatt.horsnell@ARM.com  public:
18710023Smatt.horsnell@ARM.com    ProbeListenerArgBase(ProbeManager *pm, const std::string &name)
18810023Smatt.horsnell@ARM.com        : ProbeListener(pm, name)
18910023Smatt.horsnell@ARM.com    {}
19010023Smatt.horsnell@ARM.com    virtual void notify(const Arg &val) = 0;
19110023Smatt.horsnell@ARM.com};
19210023Smatt.horsnell@ARM.com
19310023Smatt.horsnell@ARM.com/**
19410023Smatt.horsnell@ARM.com * ProbeListenerArg generates a listener for the class of Arg and the
19510023Smatt.horsnell@ARM.com * class type T which is the class containing the function that notify will
19610023Smatt.horsnell@ARM.com * call.
19710023Smatt.horsnell@ARM.com *
19810023Smatt.horsnell@ARM.com * Note that the function is passed as a pointer on construction.
19910023Smatt.horsnell@ARM.com */
20010023Smatt.horsnell@ARM.comtemplate <class T, class Arg>
20110023Smatt.horsnell@ARM.comclass ProbeListenerArg : public ProbeListenerArgBase<Arg>
20210023Smatt.horsnell@ARM.com{
20310023Smatt.horsnell@ARM.com  private:
20410023Smatt.horsnell@ARM.com    T *object;
20510023Smatt.horsnell@ARM.com    void (T::* function)(const Arg &);
20610023Smatt.horsnell@ARM.com
20710023Smatt.horsnell@ARM.com  public:
20810023Smatt.horsnell@ARM.com    /**
20910023Smatt.horsnell@ARM.com     * @param obj the class of type Tcontaining the method to call on notify.
21010023Smatt.horsnell@ARM.com     * @param name the name of the ProbePoint to add this listener to.
21110023Smatt.horsnell@ARM.com     * @param func a pointer to the function on obj (called on notify).
21210023Smatt.horsnell@ARM.com     */
21310023Smatt.horsnell@ARM.com    ProbeListenerArg(T *obj, const std::string &name, void (T::* func)(const Arg &))
21410023Smatt.horsnell@ARM.com        : ProbeListenerArgBase<Arg>(obj->getProbeManager(), name),
21510023Smatt.horsnell@ARM.com          object(obj),
21610023Smatt.horsnell@ARM.com          function(func)
21710023Smatt.horsnell@ARM.com    {}
21810023Smatt.horsnell@ARM.com
21910023Smatt.horsnell@ARM.com    /**
22010023Smatt.horsnell@ARM.com     * @brief called when the ProbePoint calls notify. This is a shim through to
22110023Smatt.horsnell@ARM.com     *        the function passed during construction.
22210023Smatt.horsnell@ARM.com     * @param val the argument value to pass.
22310023Smatt.horsnell@ARM.com     */
22410023Smatt.horsnell@ARM.com    virtual void notify(const Arg &val) { (object->*function)(val); }
22510023Smatt.horsnell@ARM.com};
22610023Smatt.horsnell@ARM.com
22710023Smatt.horsnell@ARM.com/**
22810023Smatt.horsnell@ARM.com * ProbePointArg generates a point for the class of Arg. As ProbePointArgs talk
22910023Smatt.horsnell@ARM.com * directly to ProbeListenerArgs of the same type, we can store the vector of
23010023Smatt.horsnell@ARM.com * ProbeListeners as their Arg type (and not as base type).
23110023Smatt.horsnell@ARM.com *
23210023Smatt.horsnell@ARM.com * Methods are provided to addListener, removeListener and notify.
23310023Smatt.horsnell@ARM.com */
23410023Smatt.horsnell@ARM.comtemplate <typename Arg>
23510023Smatt.horsnell@ARM.comclass ProbePointArg : public ProbePoint
23610023Smatt.horsnell@ARM.com{
23710023Smatt.horsnell@ARM.com    /** The attached listeners. */
23810023Smatt.horsnell@ARM.com    std::vector<ProbeListenerArgBase<Arg> *> listeners;
23910023Smatt.horsnell@ARM.com
24010023Smatt.horsnell@ARM.com  public:
24110023Smatt.horsnell@ARM.com    ProbePointArg(ProbeManager *manager, std::string name)
24210023Smatt.horsnell@ARM.com        : ProbePoint(manager, name)
24310023Smatt.horsnell@ARM.com    {
24410023Smatt.horsnell@ARM.com    }
24510023Smatt.horsnell@ARM.com
24610023Smatt.horsnell@ARM.com    /**
24710023Smatt.horsnell@ARM.com     * @brief adds a ProbeListener to this ProbePoints notify list.
24810023Smatt.horsnell@ARM.com     * @param l the ProbeListener to add to the notify list.
24910023Smatt.horsnell@ARM.com     */
25010023Smatt.horsnell@ARM.com    void addListener(ProbeListener *l)
25110023Smatt.horsnell@ARM.com    {
25210023Smatt.horsnell@ARM.com        // check listener not already added
25310023Smatt.horsnell@ARM.com        if (std::find(listeners.begin(), listeners.end(), l) == listeners.end()) {
25410023Smatt.horsnell@ARM.com            listeners.push_back(static_cast<ProbeListenerArgBase<Arg> *>(l));
25510023Smatt.horsnell@ARM.com        }
25610023Smatt.horsnell@ARM.com    }
25710023Smatt.horsnell@ARM.com
25810023Smatt.horsnell@ARM.com    /**
25910023Smatt.horsnell@ARM.com     * @brief remove a ProbeListener from this ProbePoints notify list.
26010023Smatt.horsnell@ARM.com     * @param l the ProbeListener to remove from the notify list.
26110023Smatt.horsnell@ARM.com     */
26210023Smatt.horsnell@ARM.com    void removeListener(ProbeListener *l)
26310023Smatt.horsnell@ARM.com    {
26410023Smatt.horsnell@ARM.com        listeners.erase(std::remove(listeners.begin(), listeners.end(), l),
26510023Smatt.horsnell@ARM.com                        listeners.end());
26610023Smatt.horsnell@ARM.com    }
26710023Smatt.horsnell@ARM.com
26810023Smatt.horsnell@ARM.com    /**
26910023Smatt.horsnell@ARM.com     * @brief called at the ProbePoint call site, passes arg to each listener.
27010023Smatt.horsnell@ARM.com     * @param arg the argument to pass to each listener.
27110023Smatt.horsnell@ARM.com     */
27210023Smatt.horsnell@ARM.com    void notify(const Arg &arg)
27310023Smatt.horsnell@ARM.com    {
27410023Smatt.horsnell@ARM.com        for (auto l = listeners.begin(); l != listeners.end(); ++l) {
27510023Smatt.horsnell@ARM.com            (*l)->notify(arg);
27610023Smatt.horsnell@ARM.com        }
27710023Smatt.horsnell@ARM.com    }
27810023Smatt.horsnell@ARM.com};
27910023Smatt.horsnell@ARM.com#endif//__SIM_PROBE_PROBE_HH__
280