25 #ifndef PXR_BASE_TRACE_COLLECTOR_H 26 #define PXR_BASE_TRACE_COLLECTOR_H 30 #include "pxr/base/trace/api.h" 31 #include "pxr/base/trace/concurrentList.h" 32 #include "pxr/base/trace/collection.h" 33 #include "pxr/base/trace/event.h" 34 #include "pxr/base/trace/key.h" 35 #include "pxr/base/trace/threads.h" 40 #include "pxr/base/tf/pyTracing.h" 52 #include <tbb/spin_mutex.h> 54 PXR_NAMESPACE_OPEN_SCOPE
56 class TraceScopeHolder;
72 TF_MALLOC_TAG_NEW(
"Trace",
"TraceCollector");
75 using ThisPtr = TraceCollectorPtr;
93 return (_isEnabled.load(std::memory_order_acquire) == 1);
105 #ifdef PXR_PYTHON_SUPPORT_ENABLED 108 return _isPythonTracingEnabled.load(std::memory_order_acquire) != 0;
113 #endif // PXR_PYTHON_SUPPORT_ENABLED 120 TRACE_API
void Clear();
133 template <
typename Category = DefaultCategory>
135 if (ARCH_LIKELY(!Category::IsEnabled())) {
138 return _BeginEvent(key, Category::GetId());
146 template <
typename Category = DefaultCategory>
148 if (ARCH_LIKELY(!Category::IsEnabled())) {
151 _BeginEventAtTime(key, ms, Category::GetId());
162 template <
typename Category = DefaultCategory>
164 if (ARCH_LIKELY(!Category::IsEnabled())) {
167 return _EndEvent(key, Category::GetId());
175 template <
typename Category = DefaultCategory>
177 if (ARCH_LIKELY(!Category::IsEnabled())) {
180 _EndEventAtTime(key, ms, Category::GetId());
188 template <
typename Category = DefaultCategory>
190 if (ARCH_LIKELY(!Category::IsEnabled())) {
193 return _MarkerEvent(key, Category::GetId());
201 template <
typename Category = DefaultCategory>
203 if (ARCH_LIKELY(!Category::IsEnabled())) {
206 _MarkerEventAtTime(key, ms, Category::GetId());
214 template <
typename Category = DefaultCategory>
216 if (ARCH_LIKELY(!Category::IsEnabled()))
219 _BeginScope(_key, Category::GetId());
227 template <
typename Category,
typename... Args>
229 const TraceKey& key, Args&&... args) {
230 static_assert(
sizeof...(Args) %2 == 0,
231 "Data arguments must come in pairs");
233 if (ARCH_LIKELY(!Category::IsEnabled()))
236 _PerThreadData *threadData = _GetThreadData();
237 threadData->BeginScope(key, Category::GetId());
238 _StoreDataRec(threadData, Category::GetId(), std::forward<Args>(args)...);
245 template <
typename... Args>
247 static_assert(
sizeof...(Args) %2 == 0,
248 "Data arguments must come in pairs");
252 BeginScope<DefaultCategory>(key,
253 std::forward<Args>(args)...);
260 template <
typename Category = DefaultCategory>
262 if (ARCH_LIKELY(!Category::IsEnabled()))
265 _EndScope(key, Category::GetId());
276 Scope(
const TraceKey& key, TimeStamp start, TimeStamp stop) noexcept;
284 template <
typename Category = DefaultCategory>
286 if (ARCH_LIKELY(!Category::IsEnabled()))
288 _PerThreadData *threadData = _GetThreadData();
289 threadData->EmplaceEvent(
290 TraceEvent::Timespan, key, start, stop, Category::GetId());
296 template <
typename Category,
typename... Args>
298 static_assert(
sizeof...(Args) %2 == 0,
299 "Data arguments must come in pairs");
301 if (ARCH_LIKELY(!Category::IsEnabled()))
304 _PerThreadData *threadData = _GetThreadData();
305 _StoreDataRec(threadData, Category::GetId(), std::forward<Args>(args)...);
314 template <
typename... Args>
316 static_assert(
sizeof...(Args) %2 == 0,
317 "Data arguments must come in pairs");
319 ScopeArgs<DefaultCategory>(std::forward<Args>(args)...);
329 template <
typename Category = DefaultCategory>
331 if (ARCH_LIKELY(!Category::IsEnabled()))
334 _PerThreadData *threadData = _GetThreadData();
335 threadData->EmplaceEvent(
336 TraceEvent::Marker, key, Category::GetId());
343 template <
typename Category = DefaultCategory,
typename T>
345 if (ARCH_UNLIKELY(Category::IsEnabled())) {
346 _StoreData(_GetThreadData(), key, Category::GetId(), value);
351 template <
typename Category = DefaultCategory>
355 if (ARCH_UNLIKELY(Category::IsEnabled())) {
356 _PerThreadData *threadData = _GetThreadData();
357 threadData->EmplaceEvent(
358 TraceEvent::CounterDelta, key, delta, Category::GetId());
363 template <
typename Category = DefaultCategory>
365 if (ARCH_UNLIKELY(Category::IsEnabled())) {
366 _PerThreadData *threadData = _GetThreadData();
367 threadData->CounterDelta(key, delta, Category::GetId());
372 template <
typename Category = DefaultCategory>
375 if (ARCH_UNLIKELY(Category::IsEnabled())) {
376 _PerThreadData *threadData = _GetThreadData();
377 threadData->EmplaceEvent(
378 TraceEvent::CounterValue, key, value, Category::GetId());
384 template <
typename Category = DefaultCategory>
387 if (ARCH_UNLIKELY(Category::IsEnabled())) {
388 _PerThreadData *threadData = _GetThreadData();
389 threadData->CounterValue(key, value, Category::GetId());
412 class _PerThreadData;
416 TRACE_API _PerThreadData* _GetThreadData() noexcept;
420 TRACE_API
void _BeginEventAtTime(
425 TRACE_API
void _EndEventAtTime(
430 TRACE_API
void _MarkerEventAtTime(
438 _PerThreadData *threadData = _GetThreadData();
439 threadData->BeginScope(key, cat);
446 TRACE_API
void _MeasureScopeOverhead();
448 #ifdef PXR_PYTHON_SUPPORT_ENABLED 451 #endif // PXR_PYTHON_SUPPORT_ENABLED 454 template <
typename T,
455 typename std::enable_if<
456 sizeof(T) <=
sizeof(uintptr_t)
457 && !std::is_pointer<T>::value ,
int>::type = 0>
458 void _StoreData(_PerThreadData* threadData,
const TraceKey &key,
460 threadData->StoreData(key, value, cat);
464 template <
typename T,
465 typename std::enable_if<
466 (
sizeof(T) >
sizeof(uintptr_t))
467 && !std::is_pointer<T>::value,
int>::type = 0>
468 void _StoreData(_PerThreadData* threadData,
const TraceKey &key,
470 threadData->StoreLargeData(key, value, cat);
475 _PerThreadData* threadData,
479 threadData->StoreLargeData(key, value, cat);
484 _PerThreadData* threadData,
487 const std::string& value) {
488 threadData->StoreLargeData(key, value.c_str(), cat);
492 template <
typename K,
typename T,
typename... Args>
495 const T& value, Args&&... args) {
496 _StoreData(threadData, std::forward<K>(key), cat, value);
497 _StoreDataRec(threadData, cat, std::forward<Args>(args)...);
506 class _PerThreadData {
527 AtomicRef lock(_writing);
528 _BeginScope(key, cat);
532 AtomicRef lock(_writing);
536 TRACE_API
void CounterDelta(
539 TRACE_API
void CounterValue(
542 template <
typename T>
545 AtomicRef lock(_writing);
546 _events.load(std::memory_order_acquire)->EmplaceBack(
547 TraceEvent::Data, key, data, cat);
550 template <
typename T>
553 AtomicRef lock(_writing);
554 EventList* events = _events.load(std::memory_order_acquire);
555 const auto* cached = events->StoreData(data);
556 events->EmplaceBack(TraceEvent::Data, key, cached, cat);
559 template <
typename... Args>
560 void EmplaceEvent(Args&&... args) {
561 AtomicRef lock(_writing);
562 _events.load(std::memory_order_acquire)->EmplaceBack(
563 std::forward<Args>(args)...);
566 #ifdef PXR_PYTHON_SUPPORT_ENABLED 567 void PushPyScope(
const Key& key,
bool enabled);
568 void PopPyScope(
bool enabled);
569 #endif // PXR_PYTHON_SUPPORT_ENABLED 573 std::unique_ptr<EventList> GetCollectionData();
578 _events.load(std::memory_order_acquire)->EmplaceBack(
579 TraceEvent::Begin, key, cat);
585 mutable std::atomic<bool> _writing;
586 std::atomic<EventList*> _events;
590 AtomicRef(std::atomic<bool>& b) : _bool(b) {
591 _bool.store(
true, std::memory_order_release);
594 _bool.store(
false, std::memory_order_release);
597 std::atomic<bool>& _bool;
610 std::vector<PyScope> _pyScopes;
613 TRACE_API
static std::atomic<int> _isEnabled;
620 TimeStamp _measuredScopeOverhead;
622 std::atomic<int> _isPythonTracingEnabled;
623 TfPyTraceFnId _pyTraceFnId;
628 PXR_NAMESPACE_CLOSE_SCOPE
630 #endif // PXR_BASE_TRACE_COLLECTOR_H const std::string & GetLabel()
Return the label associated with this collector.
static bool IsEnabled()
Returns the result of TraceCollector::IsEnabled.
void StoreData(const TraceKey &key, const T &value)
Record a data event with the given key and value if Category is enabled.
Manage a single instance of an object.
TRACE_API void CreateCollection()
Produces a TraceCollection from all the events that recorded in the collector and issues a TraceColle...
TRACE_API void SetEnabled(bool isEnabled)
Enables or disables collection of events for DefaultCategory.
Manage a single instance of an object (see.
void RecordCounterValue(const Key &key, double value)
Record a counter value for a name key and delta value if Category is enabled.
void BeginEventAtTime(const Key &key, double ms)
Record a begin event with key at a specified time if Category is enabled.
#define TF_DECLARE_WEAK_PTRS(type)
Define standard weak pointer types.
Standard pointer typedefs.
void MarkerEventStatic(const TraceKey &key)
Record a scope event described by key that started at start if Category is enabled.
void MarkerEventAtTime(const Key &key, double ms)
Record a marker event with key at a specified time if Category is enabled.
TimeStamp EndEvent(const Key &key)
Record an end event with key if Category is enabled.
This class represents an identifier for a thread.
uint64_t TimeStamp
Time in "ticks".
void RecordCounterValue(const TraceKey &key, double value)
Record a counter value for a name key if Category is enabled.
bool IsPythonTracingEnabled() const
Returns whether automatic tracing of all python scopes is enabled.
Pointer storage with deletion detection.
#define TF_DECLARE_WEAK_AND_REF_PTRS(type)
Define standard weak, ref, and vector pointer types.
static constexpr TraceCategoryId GetId()
Returns TraceCategory::Default.
TRACE_API void Clear()
Clear all pending events from the collector.
This class stores data used to create dynamic keys which can be referenced in TraceEvent instances.
TimeStamp BeginEvent(const Key &key)
Record a begin event with key if Category is enabled.
void BeginScope(const TraceKey &key, Args &&... args)
Record a begin event for a scope described by key and store data arguments if Category is enabled.
void Scope(const TraceKey &key, TimeStamp start, TimeStamp stop)
Record a scope event described by key that started at start if Category is enabled.
Default Trace category which corresponds to events stored for TRACE_ macros.
void EndEventAtTime(const Key &key, double ms)
Record an end event with key at a specified time if Category is enabled.
void BeginScope(const TraceKey &key, Args &&... args)
Record a begin event for a scope described by key and a specified category and store data arguments i...
void ScopeArgs(Args &&... args)
Record multiple data events with the default category if collection of events is enabled.
TimeStamp MarkerEvent(const Key &key)
Record a marker event with key if Category is enabled.
static TRACE_API TraceCollector & GetInstance()
Returns the singleton instance.
This is a singleton class that records TraceEvent instances and populates TraceCollection instances.
void EndScope(const TraceKey &key)
Record an end event described by key if Category is enabled.
void RecordCounterDelta(const Key &key, double delta)
Record a counter delta for a name key if Category is enabled.
Structure passed to python trace functions.
static T & GetInstance()
Return a reference to an object of type T, creating it if necessary.
void BeginScope(const TraceKey &_key)
Record a begin event for a scope described by key if Category is enabled.
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.
This class represents an ordered collection of TraceEvents and the TraceDynamicKeys and data that the...
static bool IsEnabled()
Returns whether collection of events is enabled for DefaultCategory.
TRACE_API void SetPythonTracingEnabled(bool enabled)
Set whether automatic tracing of all python scopes is enabled.
TRACE_API TimeStamp GetScopeOverhead() const
Return the overhead cost to measure a scope.
uint32_t TraceCategoryId
Categories that a TraceReporter can use to filter events.
Enable a concrete base class for use with TfWeakPtr.
void RecordCounterDelta(const TraceKey &key, double delta)
Record a counter delta for a name key if Category is enabled.
void ScopeArgs(Args &&... args)
Record multiple data events with category cat if Category is enabled.
A wrapper around a TraceStaticKeyData pointer that is stored in TraceEvent instances.