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