MeVisLabToolboxReference
|
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_