trace.h
Go to the documentation of this file.
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_TRACE_H
26 #define PXR_BASE_TRACE_TRACE_H
27 
29 
30 #include "pxr/pxr.h"
31 
32 #include "pxr/base/trace/api.h"
33 #include "pxr/base/trace/collector.h"
34 
35 #include "pxr/base/tf/preprocessorUtilsLite.h"
36 
37 #include <atomic>
38 
39 #if !defined(TRACE_DISABLE)
40 
43 #define TRACE_FUNCTION() \
44  _TRACE_FUNCTION_INSTANCE(__LINE__, __ARCH_FUNCTION__, __ARCH_PRETTY_FUNCTION__)
45 
48 #define TRACE_SCOPE(name) \
49  _TRACE_SCOPE_INSTANCE(__LINE__, name)
50 
53 #define TRACE_FUNCTION_SCOPE(name) \
54  _TRACE_FUNCTION_SCOPE_INSTANCE( \
55  __LINE__, __ARCH_FUNCTION__, __ARCH_PRETTY_FUNCTION__, name)
56 
58 #define TRACE_MARKER(name) \
59  _TRACE_MARKER_INSTANCE(__LINE__, name)
60 
62 #define TRACE_MARKER_DYNAMIC(name) \
63  _TRACE_MARKER_DYNAMIC_INSTANCE(__LINE__, name)
64 
70 #define TRACE_COUNTER_DELTA(name, delta) \
71  _TRACE_COUNTER_INSTANCE(__LINE__, name, delta, /* isDelta */ true)
72 
77 #define TRACE_COUNTER_DELTA_DYNAMIC(name, delta) \
78  TraceCollector::GetInstance().RecordCounterDelta(name, delta);
79 
83 #define TRACE_COUNTER_VALUE(name, value) \
84  _TRACE_COUNTER_INSTANCE(__LINE__, name, value, /* isDelta */ false)
85 
90 #define TRACE_COUNTER_VALUE_DYNAMIC(name, value) \
91  TraceCollector::GetInstance().RecordCounterValue(name, value);
92 
111 #define TRACE_COUNTER_DELTA_CODE(name, code) \
112  _TRACE_COUNTER_CODE_INSTANCE(__LINE__, name, code, true)
113 
119 #define TRACE_FUNCTION_DYNAMIC(name) \
120  _TRACE_FUNCTION_DYNAMIC_INSTANCE(__LINE__, __ARCH_FUNCTION__, __ARCH_PRETTY_FUNCTION__, name)
121 
127 #define TRACE_SCOPE_DYNAMIC(name) \
128  _TRACE_SCOPE_DYNAMIC_INSTANCE(__LINE__, name)
129 
130 
135 
136 
137 #define _TRACE_FUNCTION_INSTANCE(instance, name, prettyName) \
138 constexpr static PXR_NS::TraceStaticKeyData \
139  TF_PP_CAT(TraceKeyData_, instance)(name, prettyName); \
140 PXR_NS::TraceScopeAuto TF_PP_CAT(TraceScopeAuto_, instance)(\
141  TF_PP_CAT(TraceKeyData_, instance));
142 
143 #define _TRACE_SCOPE_INSTANCE(instance, name) \
144 constexpr static PXR_NS::TraceStaticKeyData \
145  TF_PP_CAT(TraceKeyData_, instance)(name); \
146 PXR_NS::TraceScopeAuto TF_PP_CAT(TraceScopeAuto_, instance)(\
147  TF_PP_CAT(TraceKeyData_, instance));
148 
149 #define _TRACE_FUNCTION_SCOPE_INSTANCE(instance, name, prettyName, scopeName) \
150 constexpr static PXR_NS::TraceStaticKeyData \
151  TF_PP_CAT(TraceKeyData_, instance)(name, prettyName, scopeName); \
152 PXR_NS::TraceScopeAuto TF_PP_CAT(TraceScopeAuto_, instance)(\
153  TF_PP_CAT(TraceKeyData_, instance));
154 
155 #define _TRACE_MARKER_INSTANCE(instance, name) \
156 constexpr static PXR_NS::TraceStaticKeyData \
157  TF_PP_CAT(TraceKeyData_, instance)(name); \
158  TraceCollector::GetInstance().MarkerEventStatic(TF_PP_CAT(TraceKeyData_, instance));
159 
160 #define _TRACE_COUNTER_INSTANCE(instance, name, value, isDelta) \
161 constexpr static PXR_NS::TraceStaticKeyData \
162  TF_PP_CAT(TraceKeyData_, instance)(name); \
163 static PXR_NS::TraceCounterHolder \
164  TF_PP_CAT(TraceCounterHolder_, instance) \
165  (TF_PP_CAT(TraceKeyData_, instance)); \
166 TF_PP_CAT(TraceCounterHolder_, instance).Record(value, isDelta);
167 
168 #define _TRACE_COUNTER_CODE_INSTANCE(instance, name, code, isDelta) \
169 static PXR_NS::TraceCounterHolder \
170  TF_PP_CAT(TraceCounterHolder_, instance)(name); \
171 if (TF_PP_CAT(TraceCounterHolder_, instance).IsEnabled()) { \
172  double value = 0.0; \
173  code \
174  TF_PP_CAT(TraceCounterHolder_, instance).RecordDelta(value, isDelta); \
175 }
176 
177 #define _TRACE_FUNCTION_DYNAMIC_INSTANCE(instance, fnName, fnPrettyName, name) \
178 PXR_NS::TraceAuto TF_PP_CAT(TraceAuto_, instance)(fnName, fnPrettyName, name)
179 
180 #define _TRACE_SCOPE_DYNAMIC_INSTANCE(instance, str) \
181 PXR_NS::TraceAuto TF_PP_CAT(TraceAuto_, instance)(str)
182 
183 #define _TRACE_MARKER_DYNAMIC_INSTANCE(instance, name) \
184  TraceCollector::GetInstance().MarkerEvent(name);
185 
186 #else // TRACE_DISABLE
187 
188 #define TRACE_FUNCTION()
189 #define TRACE_FUNCTION_DYNAMIC(name)
190 #define TRACE_SCOPE(name)
191 #define TRACE_SCOPE_DYNAMIC(name)
192 #define TRACE_FUNCTION_SCOPE(name)
193 #define TRACE_MARKER(name)
194 #define TRACE_MARKER_DYNAMIC(name)
195 
196 #endif // TRACE_DISABLE
197 
198 PXR_NAMESPACE_OPEN_SCOPE
199 
207 public:
210  explicit TraceScopeAuto(const TraceStaticKeyData& key) noexcept
211  : _key(&key)
212  , _intervalTimer(/*start=*/TraceCollector::IsEnabled()) {
213  }
214 
217  template < typename... Args>
218  TraceScopeAuto(const TraceStaticKeyData& key, Args&&... args)
219  : _key(&key)
220  , _intervalTimer(/*start=*/false) {
222  _intervalTimer.Start();
224  ::GetInstance().ScopeArgs(std::forward<Args>(args)...);
225  }
226  }
227 
230  ~TraceScopeAuto() noexcept {
231  if (_intervalTimer.IsStarted()) {
232  TraceCollector::TimeStamp stopTicks =
233  _intervalTimer.GetCurrentTicks();
235  *_key, _intervalTimer.GetStartTicks(), stopTicks);
236  }
237  }
238 
239 private:
240  const TraceStaticKeyData* const _key;
241  ArchIntervalTimer _intervalTimer;
242 };
243 
255 struct TraceAuto {
258  TraceAuto(const char *funcName, const char *prettyFuncName,
259  const std::string &name)
260  : _key(_CreateKeyString(funcName, prettyFuncName, name)) {
261  std::atomic_thread_fence(std::memory_order_seq_cst);
262  _collector = &TraceCollector::GetInstance();
263  _collector->BeginEvent(_key);
264  std::atomic_thread_fence(std::memory_order_seq_cst);
265  }
266 
269  explicit TraceAuto(const TfToken& key)
270  : _key(key) {
271  std::atomic_thread_fence(std::memory_order_seq_cst);
272  _collector = &TraceCollector::GetInstance();
273  _collector->BeginEvent(_key);
274  std::atomic_thread_fence(std::memory_order_seq_cst);
275  }
276 
279  explicit TraceAuto(const std::string& key)
280  : TraceAuto(TfToken(key)) {}
281 
282  // Non-copyable
283  //
284  TraceAuto(const TraceAuto &) = delete;
285  TraceAuto& operator=(const TraceAuto &) = delete;
286 
287  // Non-movable
288  //
289  TraceAuto(TraceAuto &&) = delete;
290  TraceAuto& operator=(TraceAuto &&) = delete;
291 
295  std::atomic_thread_fence(std::memory_order_seq_cst);
296  _collector->EndEvent(_key);
297  std::atomic_thread_fence(std::memory_order_seq_cst);
298  }
299 
300 private:
301  static std::string _CreateKeyString(
302  const char *funcName,
303  const char *prettyFuncName,
304  const std::string &name) {
305  std::string key = ArchGetPrettierFunctionName(funcName, prettyFuncName);
306  key += " [";
307  key += name;
308  key += "]";
309  return key;
310  }
311 
312  TraceCollector* _collector;
313  TraceDynamicKey _key;
314 };
315 
323 public:
326  explicit TraceCounterHolder(const TraceKey& key)
327  : _key(key) {}
328 
331  bool IsEnabled() const {
332  return TraceCollector::IsEnabled();
333  }
334 
337  void Record(double value, bool delta) {
338  if (delta) {
340  } else {
342  }
343  }
344 
345 private:
346  TraceKey _key;
347 };
348 
349 PXR_NAMESPACE_CLOSE_SCOPE
350 
351 #endif // PXR_BASE_TRACE_TRACE_H
Holds on to a counter key, as well as the global collector for fast lookup.
Definition: trace.h:322
TraceCounterHolder(const TraceKey &key)
Constructor used by TRACE_COUNTER_* macro.
Definition: trace.h:326
TimeStamp EndEvent(const Key &key)
Record an end event with key if Category is enabled.
Definition: collector.h:163
TraceAuto(const char *funcName, const char *prettyFuncName, const std::string &name)
Constructor taking function name, pretty function name and a scope name.
Definition: trace.h:258
void RecordCounterValue(const TraceKey &key, double value)
Record a counter value for a name key if Category is enabled.
Definition: collector.h:373
A class which records a begin event when it is constructed, and a matching end event when it is destr...
Definition: trace.h:255
This class stores data used to create dynamic keys which can be referenced in TraceEvent instances.
Definition: dynamicKey.h:42
TimeStamp BeginEvent(const Key &key)
Record a begin event with key if Category is enabled.
Definition: collector.h:134
uint64_t GetCurrentTicks()
Read and return the current time.
Definition: timing.h:198
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:87
bool IsStarted() const
Return true if this timer is started.
Definition: timing.h:188
void Start()
Start the timer, or reset the start time if it has already been started.
Definition: timing.h:177
static TRACE_API TraceCollector & GetInstance()
Returns the singleton instance.
Definition: collector.h:82
A class which records a timestamp when it is created and a scope event when it is destructed.
Definition: trace.h:206
This is a singleton class that records TraceEvent instances and populates TraceCollection instances.
Definition: collector.h:69
uint64_t GetStartTicks() const
Return this timer's start time, or 0 if it hasn't been started.
Definition: timing.h:193
~TraceAuto()
Destructor.
Definition: trace.h:294
A simple timer class for measuring an interval of time using the ArchTickTimer facilities.
Definition: timing.h:166
static TRACE_API void Scope(const TraceKey &key, TimeStamp start, TimeStamp stop) noexcept
Record a scope event described by key that started at start for the DefaultCategory.
TraceScopeAuto(const TraceStaticKeyData &key, Args &&... args)
Constructor that also records scope arguments.
Definition: trace.h:218
TraceAuto(const TfToken &key)
Constructor taking a TfToken key.
Definition: trace.h:269
bool IsEnabled() const
Returns whether the TraceCollector is enabled or not.
Definition: trace.h:331
TraceScopeAuto(const TraceStaticKeyData &key) noexcept
Constructor for TRACE_FUNCTION macro.
Definition: trace.h:210
static bool IsEnabled()
Returns whether collection of events is enabled for DefaultCategory.
Definition: collector.h:92
void Record(double value, bool delta)
Records a counter delta value if the TraceCollector is enabled.
Definition: trace.h:337
TraceAuto(const std::string &key)
Constructor taking a string key.
Definition: trace.h:279
~TraceScopeAuto() noexcept
Destructor.
Definition: trace.h:230
void RecordCounterDelta(const TraceKey &key, double delta)
Record a counter delta for a name key if Category is enabled.
Definition: collector.h:352
ARCH_API std::string ArchGetPrettierFunctionName(const std::string &function, const std::string &prettyFunction)
Return well formatted function name.
void ScopeArgs(Args &&... args)
Record multiple data events with category cat if Category is enabled.
Definition: collector.h:297
This class holds data necessary to create keys for TraceEvent instances.
Definition: staticKeyData.h:43
A wrapper around a TraceStaticKeyData pointer that is stored in TraceEvent instances.
Definition: key.h:40