00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef COP2_DebugTiming_H
00022 #define COP2_DebugTiming_H
00023
00024 #include <iostream.h>
00025 #include <UT/UT_Lock.h>
00026 #include <UT/UT_String.h>
00027 #include <UT/UT_SymbolTable.h>
00028 #include <SYS/SYS_Math.h>
00029 #include <OP/OP_Node.h>
00030
00031 #include "COP2_API.h"
00032
00033 class COP2_DebugTimingTable;
00034
00035 class COP2_API COP2_DebugTimingNode
00036 {
00037 public:
00038 COP2_DebugTimingNode(const char *nodepath)
00039 : myNodePath(nodepath, 1),
00040 myNumCooks(0),
00041 myTotalCookTime(0.0),
00042 myMinCookTime(0.0),
00043 myMaxCookTime(0.0)
00044 { }
00045
00046 void addCookTime(double time)
00047 {
00048 if(myNumCooks == 0)
00049 {
00050 myMinCookTime = time;
00051 myMaxCookTime = time;
00052 }
00053 else
00054 {
00055 myMinCookTime = SYSmin(time, myMinCookTime);
00056 myMaxCookTime = SYSmax(time, myMaxCookTime);
00057 }
00058 myTotalCookTime += time;
00059 myNumCooks++;
00060 }
00061
00062 void print(ostream &os) const
00063 {
00064 if(myNumCooks > 0.0)
00065 os << myNodePath << "\n " << myNumCooks << " "
00066 << myTotalCookTime <<"s min " << myMinCookTime << "s max "
00067 << myMaxCookTime << "s avg "
00068 << (myTotalCookTime / myNumCooks) << "s";
00069 else
00070 os << myNodePath << " not cooked.";
00071 }
00072
00073 UT_String myNodePath;
00074 int myNumCooks;
00075 double myTotalCookTime;
00076 double myMinCookTime;
00077 double myMaxCookTime;
00078 };
00079
00080 struct cop2_timing_entry_data
00081 {
00082 ostream *os;
00083 double total_time;
00084 };
00085
00086
00087 inline int printEntry(UT_Thing &data, const char *, void *vdata)
00088 {
00089 COP2_DebugTimingNode *node = (COP2_DebugTimingNode *) ((void *)data);
00090 cop2_timing_entry_data *pdata = (cop2_timing_entry_data *) vdata;
00091
00092 node->print(*pdata->os);
00093 *pdata->os << endl;
00094 pdata->total_time += node->myTotalCookTime;
00095 return 1;
00096 }
00097
00098 inline int clearEntry(UT_Thing &data, const char *, void *)
00099 {
00100 COP2_DebugTimingNode *node = (COP2_DebugTimingNode *) ((void *)data);
00101 delete node;
00102 return 1;
00103 }
00104
00105
00106 class COP2_API COP2_DebugTimingTable
00107 {
00108 public:
00109 COP2_DebugTimingTable() : myTotal(0.0) {}
00110 ~COP2_DebugTimingTable()
00111 {
00112 myTable.traverse(clearEntry, NULL);
00113 }
00114
00115 void addCopTiming(OP_Node *copnode, double time)
00116 {
00117 UT_String path;
00118 UT_Thing data;
00119 COP2_DebugTimingNode *tnode = NULL;
00120
00121 copnode->getFullPath(path);
00122
00123 myTableLock.lock();
00124
00125 if(myTable.findSymbol(path, &data))
00126 {
00127 tnode = (COP2_DebugTimingNode *) ((void *)data);
00128 }
00129 else
00130 {
00131 tnode = new COP2_DebugTimingNode(path);
00132 data = (void *) tnode;
00133 myTable.addSymbol(path, data);
00134 }
00135
00136 tnode->addCookTime(time);
00137
00138 myTableLock.unlock();
00139 }
00140
00141 void printTable(ostream &os)
00142 {
00143 cop2_timing_entry_data pdata;
00144 pdata.os = &os;
00145 pdata.total_time = 0.0;
00146 myTable.traverse(printEntry, &pdata);
00147 os.flush();
00148 os << "Total time: " << pdata.total_time << "s" << endl;
00149 os.flush();
00150 }
00151
00152 UT_SymbolTable myTable;
00153 UT_Lock myTableLock;
00154 double myTotal;
00155 };
00156
00157
00158
00159 #endif