MeVisLabToolboxReference
MeVis/Foundation/Sources/MLProfilingManager/Include/mlCallGraph.h
Go to the documentation of this file.
00001 // **InsertLicense** code
00002 //----------------------------------------------------------------------------------
00003 // Tree structure for holding timers.
00004 //
00005 // \file    mlCallGraph.h
00006 // \author  Marcus Barann
00007 // \date    6/2010
00008 //
00009 //----------------------------------------------------------------------------------
00010 #ifndef _ML_TIMER_TREE_H_
00011 #define _ML_TIMER_TREE_H_
00012 
00013 #include "mlProfilingManagerDllExport.h"
00014 #include "mlTimer.h"
00015 
00016 #include <map>
00017 #include <string>
00018 #include <vector>
00019 
00020 #include <iosfwd>
00021 
00022 
00023 #include <boost/shared_ptr.hpp>
00024 
00025 class MLCallGraphFunction;
00026 class MLTimeProfile;
00027 
00028 typedef boost::shared_ptr<MLCallGraphFunction> MLCallGraphFunctionPtr;
00029 
00030 
00031 typedef long double MLProfilingTimeType;
00032 
00034 struct MLPROFILINGMANAGER_EXPORT MLTimeStatistics
00035 {
00036   MLTimeStatistics() { reset(); }
00037   void reset();
00038   MLTimeStatistics& operator+=(const MLTimeStatistics& other);
00039 
00040   struct MLPROFILINGMANAGER_EXPORT Values
00041   {
00042     Values() { reset(); }
00043     Values& operator+=(const Values& other);
00044     void add(MLProfilingTimeType time);
00045     void reset();
00046     MLProfilingTimeType minimum;
00047     MLProfilingTimeType maximum;
00048     MLProfilingTimeType total;
00049   };
00050 
00051   Values elapsed;
00052   Values consumed;
00053   unsigned int count;
00054 };
00055 
00056 
00057 class MLPROFILINGMANAGER_EXPORT MLCallGraphNode
00058 {
00059 public:
00060   MLCallGraphNode(MLTimeProfile* timeProfile = NULL,
00061                   MLCallGraphNode* parent = NULL,
00062                   void* userData = NULL,
00063                   const MLCallGraphFunctionPtr& callGraphFunction = MLCallGraphFunctionPtr());
00064 
00065   ~MLCallGraphNode();
00066 
00067   MLCallGraphNode* createChild(MLTimeProfile* timeProfile, const MLCallGraphFunctionPtr& function, void* userData);
00068 
00069   const MLTimer& timer() const { return _timer; }
00070   const MLTimeProfile* timeProfile() const { return _timeProfile; }
00071   const MLCallGraphFunctionPtr& function() const { return _function; }
00072   const std::vector<MLCallGraphNode*>& children() const { return _children; }
00073   MLCallGraphNode* parent() const { return _parent; }
00074 
00077   inline bool isRecursive(const MLTimeProfile* timeProfile) const;
00078 
00080   inline bool isRecursive() const;
00081 
00082   void print(std::ostream& out, const std::string& indent = "", bool doLock=true) const;
00083 
00087   void removeFromParent();
00088 
00090   const MLTimeStatistics& statistics() const { return _statistics; }
00091 
00093   void* userData() const { return _userData; }
00094 
00096   void clearUserData() { _userData = NULL; }
00097 
00098 private:
00099   MLTimer                       _timer;
00100   MLCallGraphFunctionPtr        _function;
00101   MLCallGraphNode*              _parent;
00102   std::vector<MLCallGraphNode*> _children;
00103   MLTimeProfile*                _timeProfile;
00104   MLTimeStatistics              _statistics;
00105   void*                         _userData;
00106 
00107   friend class MLProfilingManager;
00108   friend class MLTimeProfile;
00109 };
00110 
00111 
00112 typedef unsigned long long MLCallGraphFunctionId;
00113 
00114 class MLPROFILINGMANAGER_EXPORT MLCallGraphFunction
00115 {
00116 public:
00117   typedef std::map<MLCallGraphFunction*, MLTimeStatistics> CallGraphFunctionMap;
00118   typedef std::map<const MLTimeProfile*, MLTimeStatistics> TimeStatisticsMap;
00119 
00120 public:
00121   MLCallGraphFunction(MLCallGraphFunctionId id, const std::string& name, const std::string& filename,
00122                       int linenumber, const std::string& identifier, int type);
00123   ~MLCallGraphFunction();
00124 
00126   int type() const { return _type; }
00128   MLCallGraphFunctionId id() const { return _id; }
00130   const std::string& name() const { return _name; }
00132   const std::string& filename() const { return _filename; }
00134   int linenumber() const { return _linenumber; }
00137   const std::string& identifier() const { return _identifier; }
00138 
00140   void addCallGraphNode(MLCallGraphNode* node);
00142   void removeCallGraphNode(MLCallGraphNode* node);
00144   const std::vector<MLCallGraphNode*>& callGraphNodes() const { return _callGraphNodes; }
00146   std::vector<MLCallGraphNode*>& callGraphNodes() { return _callGraphNodes; }
00147 
00148   static std::string createIdentifier(const std::string& name, const std::string& filename, int linenumber);
00149 
00151   void addCaller(MLCallGraphFunction* function, MLProfilingTimeType elapsed, MLProfilingTimeType consumed);
00152 
00154   const CallGraphFunctionMap& callers() const { return _callers; }
00155 
00157   const CallGraphFunctionMap& callees() const { return _callees; }
00158 
00160   const MLTimeStatistics* statisticsByCaller(MLCallGraphFunction* caller);
00161 
00163   const MLTimeStatistics* statisticsByCallee(MLCallGraphFunction* callee);
00164 
00166   MLCallGraphFunction* getCallee(MLCallGraphFunction* callee);
00167 
00169   MLCallGraphFunction* getCaller(MLCallGraphFunction* caller);
00170 
00173   MLTimeStatistics& statistics() { return _statistics; }
00174   const MLTimeStatistics& statistics() const { return _statistics; }
00176 
00179   MLTimeStatistics& statistics(const MLTimeProfile* timeProfile) { return _statisticsByTimeProfile[timeProfile]; }
00180   const MLTimeStatistics& statistics(const MLTimeProfile* timeProfile) const { return const_cast< std::map<const MLTimeProfile*, MLTimeStatistics>& >(_statisticsByTimeProfile)[timeProfile]; }
00182 
00183   bool hasStatisticsForTimeProfile(const MLTimeProfile* timeProfile) const;
00184 
00185   const TimeStatisticsMap& statisticsByTimeProfile() const { return _statisticsByTimeProfile; }
00186 
00187 
00188 private:
00189   bool removeFunctionFromMap(CallGraphFunctionMap& map, MLCallGraphFunction* function);
00190 
00191 private:
00192   std::vector<MLCallGraphNode*> _callGraphNodes;
00193   MLCallGraphFunctionId         _id;
00194   std::string                   _name;
00195   std::string                   _filename;
00196   std::string                   _identifier;
00197   int                           _linenumber;
00198   int                           _type;
00199 
00200   MLTimeStatistics  _statistics;
00201   TimeStatisticsMap _statisticsByTimeProfile;
00202 
00203   CallGraphFunctionMap _callers;
00204   CallGraphFunctionMap _callees;
00205 
00206   friend class MLCallGraphNode;
00207   friend class MLTimeProfile;
00208 };
00209 
00210 
00211 inline bool MLCallGraphNode::isRecursive() const
00212 {
00213   MLCallGraphNode* next = _parent;
00214   while (next) {
00215     if (_function->_id == next->_function->_id) {
00216       return true;
00217     }
00218     next = next->_parent;
00219   }
00220   return false;
00221 }
00222 
00223 
00224 
00225 inline bool MLCallGraphNode::isRecursive(const MLTimeProfile* timeProfile_) const
00226 {
00227   MLCallGraphNode* next = _parent;
00228   while (next) {
00229     if ( (_function->_id == next->_function->_id) && (timeProfile_ == next->_timeProfile) ) {
00230       return true;
00231     }
00232     next = next->_parent;
00233   }
00234   return false;
00235 }
00236 
00237 #endif // _ML_TIMER_TREE_H_