1 // 2 // Copyright 2018 Pixar 3 // 4 // Licensed under the Apache License, Version 2.0 (the "Apache License") 5 // with the following modification; you may not use this file except in 6 // compliance with the Apache License and the following modification to it: 7 // Section 6. Trademarks. is deleted and replaced with: 8 // 9 // 6. Trademarks. This License does not grant permission to use the trade 10 // names, trademarks, service marks, or product names of the Licensor 11 // and its affiliates, except as required to comply with Section 4(c) of 12 // the License and to reproduce the content of the NOTICE file. 13 // 14 // You may obtain a copy of the Apache License at 15 // 16 // http://www.apache.org/licenses/LICENSE-2.0 17 // 18 // Unless required by applicable law or agreed to in writing, software 19 // distributed under the Apache License with the above modification is 20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 21 // KIND, either express or implied. See the Apache License for the specific 22 // language governing permissions and limitations under the Apache License. 23 // 24 25 #ifndef PXR_BASE_TRACE_REPORTER_H 26 #define PXR_BASE_TRACE_REPORTER_H 27 28 #include "pxr/pxr.h" 29 30 #include "pxr/base/trace/api.h" 31 #include "pxr/base/trace/event.h" 32 #include "pxr/base/trace/aggregateNode.h" 33 #include "pxr/base/trace/reporterBase.h" 34 35 #include "pxr/base/tf/declarePtrs.h" 36 #include "pxr/base/tf/mallocTag.h" 37 #include "pxr/base/tf/staticTokens.h" 38 39 #include <iosfwd> 40 #include <string> 41 42 PXR_NAMESPACE_OPEN_SCOPE 43 44 #define TRACE_REPORTER_TOKENS \ 45 ((warningString, "WARNING:")) 46 47 TF_DECLARE_PUBLIC_TOKENS(TraceReporterTokens, TRACE_API, TRACE_REPORTER_TOKENS); 48 49 50 TF_DECLARE_WEAK_AND_REF_PTRS(TraceAggregateTree); 51 TF_DECLARE_WEAK_AND_REF_PTRS(TraceEventNode); 52 TF_DECLARE_WEAK_AND_REF_PTRS(TraceEventTree); 53 54 TF_DECLARE_WEAK_AND_REF_PTRS(TraceReporter); 55 56 class TraceCollectionAvailable; 57 58 //////////////////////////////////////////////////////////////////////////////// 59 /// \class TraceReporter 60 /// 61 /// This class converts streams of TraceEvent objects into call trees which 62 /// can then be used as a data source to a GUI or written out to a file. 63 /// 64 class TraceReporter : 65 public TraceReporterBase { 66 public: 67 68 TF_MALLOC_TAG_NEW("Trace", "TraceReporter"); 69 70 using This = TraceReporter; 71 using ThisPtr = TraceReporterPtr; 72 using ThisRefPtr = TraceReporterRefPtr; 73 74 using Event = TraceEvent; 75 using TimeStamp = TraceEvent::TimeStamp; 76 using CounterMap = TfHashMap<TfToken, double, TfToken::HashFunctor>; 77 78 /// Create a new reporter with \a label and \a dataSource. New(const std::string & label,DataSourcePtr dataSource)79 static ThisRefPtr New(const std::string& label, 80 DataSourcePtr dataSource) { 81 return TfCreateRefPtr(new This(label, std::move(dataSource))); 82 } 83 84 /// Create a new reporter with \a label and no data source. New(const std::string & label)85 static ThisRefPtr New(const std::string& label) { 86 return TfCreateRefPtr(new This(label, nullptr)); 87 } 88 89 /// Returns the global reporter. 90 TRACE_API static TraceReporterPtr GetGlobalReporter(); 91 92 /// Destructor. 93 TRACE_API virtual ~TraceReporter(); 94 95 /// Return the label associated with this reporter. GetLabel()96 const std::string& GetLabel() { 97 return _label; 98 } 99 100 /// \name Report Generation. 101 /// @{ 102 103 /// Generates a report to the ostream \a s, dividing all times by 104 /// \a iterationCount. 105 TRACE_API void Report( 106 std::ostream &s, 107 int iterationCount=1); 108 109 /// Generates a report of the times to the ostream \a s. 110 TRACE_API void ReportTimes(std::ostream &s); 111 112 /// Generates a timeline trace report suitable for viewing in 113 /// Chrome's trace viewer. 114 TRACE_API void ReportChromeTracing(std::ostream &s); 115 116 /// @} 117 118 /// Returns the root node of the aggregated call tree. 119 TRACE_API TraceAggregateNodePtr GetAggregateTreeRoot(); 120 121 /// Returns the root node of the call tree. 122 TRACE_API TraceEventNodeRefPtr GetEventRoot(); 123 124 /// Returns the event call tree 125 TRACE_API TraceEventTreeRefPtr GetEventTree(); 126 127 /// \name Counters 128 /// @{ 129 130 /// Returns a map of counters (counter keys), associated with their total 131 /// accumulated value. Each individual event node in the tree may also hold 132 /// on to an inclusive and exclusive value for the given counter. 133 TRACE_API const CounterMap & GetCounters() const; 134 135 /// Returns the numeric index associated with a counter key. Counter values 136 /// on the event nodes will have to be looked up by the numeric index. 137 TRACE_API int GetCounterIndex(const TfToken &key) const; 138 139 /// Add a counter to the reporter. This method can be used to restore a 140 /// previous trace state and tree. Note, that the counter being added must 141 /// have a unique key and index. The method will return false if a key or 142 /// index already exists. 143 TRACE_API bool AddCounter(const TfToken &key, int index, double totalValue); 144 145 /// @} 146 147 /// This fully re-builds the event and aggregate trees from whatever the 148 /// current collection holds. It is ok to call this multiple times in case 149 /// the collection gets appended on inbetween. 150 /// 151 /// If we want to have multiple reporters per collector, this will need to 152 /// be changed so that all reporters reporting on a collector update their 153 /// respective trees. 154 TRACE_API void UpdateTraceTrees(); 155 156 /// Clears event tree and counters. 157 TRACE_API void ClearTree(); 158 159 /// \name Report options. 160 /// @{ 161 162 /// This affects only stack trace event reporting. If \c true then all 163 /// events in a function are grouped together otherwise events are split 164 /// out by address. 165 TRACE_API void SetGroupByFunction(bool); 166 167 /// Returns the current group-by-function state. 168 TRACE_API bool GetGroupByFunction() const; 169 170 /// When stack trace event reporting, this sets whether or not recursive 171 /// calls are folded in the output. Recursion folding is useful when 172 /// the stacks contain deep recursive structures. 173 TRACE_API void SetFoldRecursiveCalls(bool); 174 175 /// Returns the current setting for recursion folding for stack trace 176 /// event reporting. 177 TRACE_API bool GetFoldRecursiveCalls() const; 178 179 /// @} 180 181 /// Creates a valid TraceAggregateNode::Id object. 182 /// This should be used by very few clients for certain special cases. 183 /// For most cases, the TraceAggregateNode::Id object should be created and 184 /// populated internally within the Reporter object itself. 185 TRACE_API static TraceAggregateNode::Id CreateValidEventId(); 186 187 protected: 188 189 TRACE_API TraceReporter(const std::string& label, 190 DataSourcePtr dataSource); 191 192 private: 193 void _ProcessCollection(const TraceReporterBase::CollectionPtr&) override; 194 void _RebuildEventAndAggregateTrees(); 195 void _PrintTimes(std::ostream &s); 196 197 private: 198 std::string _label; 199 200 bool _groupByFunction; 201 bool _foldRecursiveCalls; 202 203 TraceAggregateTreeRefPtr _aggregateTree; 204 TraceEventTreeRefPtr _eventTree; 205 }; 206 207 PXR_NAMESPACE_CLOSE_SCOPE 208 209 #endif // PXR_BASE_TRACE_REPORTER_H 210