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"
54#include <tbb/spin_mutex.h>
56PXR_NAMESPACE_OPEN_SCOPE
58class TraceScopeHolder;
77 using ThisPtr = TraceCollectorPtr;
95 return (_isEnabled.load(std::memory_order_acquire) == 1);
107#ifdef PXR_PYTHON_SUPPORT_ENABLED
110 return _isPythonTracingEnabled.load(std::memory_order_acquire) != 0;
135 template <
typename Category = DefaultCategory>
137 if (ARCH_LIKELY(!Category::IsEnabled())) {
140 return _BeginEvent(key, Category::GetId());
148 template <
typename Category = DefaultCategory>
150 if (ARCH_LIKELY(!Category::IsEnabled())) {
153 _BeginEventAtTime(key, ms, Category::GetId());
164 template <
typename Category = DefaultCategory>
166 if (ARCH_LIKELY(!Category::IsEnabled())) {
169 return _EndEvent(key, Category::GetId());
177 template <
typename Category = DefaultCategory>
179 if (ARCH_LIKELY(!Category::IsEnabled())) {
182 _EndEventAtTime(key, ms, Category::GetId());
190 template <
typename Category = DefaultCategory>
192 if (ARCH_LIKELY(!Category::IsEnabled())) {
195 return _MarkerEvent(key, Category::GetId());
203 template <
typename Category = DefaultCategory>
205 if (ARCH_LIKELY(!Category::IsEnabled())) {
208 _MarkerEventAtTime(key, ms, Category::GetId());
216 template <
typename Category = DefaultCategory>
218 if (ARCH_LIKELY(!Category::IsEnabled()))
221 _BeginScope(_key, Category::GetId());
229 template <
typename Category,
typename... Args>
231 const TraceKey& key, Args&&... args) {
232 static_assert(
sizeof...(Args) %2 == 0,
233 "Data arguments must come in pairs");
235 if (ARCH_LIKELY(!Category::IsEnabled()))
238 _PerThreadData *threadData = _GetThreadData();
239 threadData->BeginScope(key, Category::GetId());
240 _StoreDataRec(threadData, Category::GetId(), std::forward<Args>(args)...);
247 template <
typename... Args>
249 static_assert(
sizeof...(Args) %2 == 0,
250 "Data arguments must come in pairs");
254 BeginScope<DefaultCategory>(key,
255 std::forward<Args>(args)...);
262 template <
typename Category = DefaultCategory>
264 if (ARCH_LIKELY(!Category::IsEnabled()))
267 _EndScope(key, Category::GetId());
286 template <
typename Category = DefaultCategory>
288 if (ARCH_LIKELY(!Category::IsEnabled()))
290 _PerThreadData *threadData = _GetThreadData();
291 threadData->EmplaceEvent(
292 TraceEvent::Timespan, key, start, stop, Category::GetId());
298 template <
typename Category,
typename... Args>
300 static_assert(
sizeof...(Args) %2 == 0,
301 "Data arguments must come in pairs");
303 if (ARCH_LIKELY(!Category::IsEnabled()))
306 _PerThreadData *threadData = _GetThreadData();
307 _StoreDataRec(threadData, Category::GetId(), std::forward<Args>(args)...);
316 template <
typename... Args>
318 static_assert(
sizeof...(Args) %2 == 0,
319 "Data arguments must come in pairs");
321 ScopeArgs<DefaultCategory>(std::forward<Args>(args)...);
331 template <
typename Category = DefaultCategory>
333 if (ARCH_LIKELY(!Category::IsEnabled()))
336 _PerThreadData *threadData = _GetThreadData();
337 threadData->EmplaceEvent(
338 TraceEvent::Marker, key, Category::GetId());
345 template <
typename Category = DefaultCategory,
typename T>
347 if (ARCH_UNLIKELY(Category::IsEnabled())) {
348 _StoreData(_GetThreadData(), key, Category::GetId(), value);
353 template <
typename Category = DefaultCategory>
357 if (ARCH_UNLIKELY(Category::IsEnabled())) {
358 _PerThreadData *threadData = _GetThreadData();
359 threadData->EmplaceEvent(
360 TraceEvent::CounterDelta, key, delta, Category::GetId());
365 template <
typename Category = DefaultCategory>
367 if (ARCH_UNLIKELY(Category::IsEnabled())) {
368 _PerThreadData *threadData = _GetThreadData();
369 threadData->CounterDelta(key, delta, Category::GetId());
374 template <
typename Category = DefaultCategory>
377 if (ARCH_UNLIKELY(Category::IsEnabled())) {
378 _PerThreadData *threadData = _GetThreadData();
379 threadData->EmplaceEvent(
380 TraceEvent::CounterValue, key, value, Category::GetId());
386 template <
typename Category = DefaultCategory>
389 if (ARCH_UNLIKELY(Category::IsEnabled())) {
390 _PerThreadData *threadData = _GetThreadData();
391 threadData->CounterValue(key, value, Category::GetId());
414 class _PerThreadData;
418 TRACE_API _PerThreadData* _GetThreadData() noexcept;
422 TRACE_API
void _BeginEventAtTime(
427 TRACE_API
void _EndEventAtTime(
432 TRACE_API
void _MarkerEventAtTime(
440 _PerThreadData *threadData = _GetThreadData();
441 threadData->BeginScope(key, cat);
448 TRACE_API
void _MeasureScopeOverhead();
450#ifdef PXR_PYTHON_SUPPORT_ENABLED
456 template <
typename T,
457 typename std::enable_if<
458 sizeof(T) <=
sizeof(uintptr_t)
459 && !std::is_pointer<T>::value ,
int>::type = 0>
460 void _StoreData(_PerThreadData* threadData,
const TraceKey &key,
462 threadData->StoreData(key, value, cat);
466 template <
typename T,
467 typename std::enable_if<
468 (
sizeof(T) >
sizeof(uintptr_t))
469 && !std::is_pointer<T>::value,
int>::type = 0>
470 void _StoreData(_PerThreadData* threadData,
const TraceKey &key,
472 threadData->StoreLargeData(key, value, cat);
477 _PerThreadData* threadData,
481 threadData->StoreLargeData(key, value, cat);
486 _PerThreadData* threadData,
489 const std::string& value) {
490 threadData->StoreLargeData(key, value.c_str(), cat);
494 template <
typename K,
typename T,
typename... Args>
497 const T& value, Args&&... args) {
498 _StoreData(threadData, std::forward<K>(key), cat, value);
499 _StoreDataRec(threadData, cat, std::forward<Args>(args)...);
508 class _PerThreadData {
523 void BeginEventAtTime(
526 void MarkerEventAtTime(
const Key& key,
double ms,
TraceCategoryId cat);
529 AtomicRef lock(_writing);
530 _BeginScope(key, cat);
534 AtomicRef lock(_writing);
538 TRACE_API
void CounterDelta(
541 TRACE_API
void CounterValue(
544 template <
typename T>
547 AtomicRef lock(_writing);
548 _events.load(std::memory_order_acquire)->EmplaceBack(
549 TraceEvent::Data, key, data, cat);
552 template <
typename T>
555 AtomicRef lock(_writing);
556 EventList* events = _events.load(std::memory_order_acquire);
557 const auto* cached = events->StoreData(data);
558 events->EmplaceBack(TraceEvent::Data, key, cached, cat);
561 template <
typename... Args>
562 void EmplaceEvent(Args&&... args) {
563 AtomicRef lock(_writing);
564 _events.load(std::memory_order_acquire)->EmplaceBack(
565 std::forward<Args>(args)...);
568#ifdef PXR_PYTHON_SUPPORT_ENABLED
569 void PushPyScope(
const Key& key,
bool enabled);
570 void PopPyScope(
bool enabled);
575 std::unique_ptr<EventList> GetCollectionData();
580 _events.load(std::memory_order_acquire)->EmplaceBack(
581 TraceEvent::Begin, key, cat);
587 mutable std::atomic<bool> _writing;
588 std::atomic<EventList*> _events;
592 AtomicRef(std::atomic<bool>& b) : _bool(b) {
593 _bool.store(
true, std::memory_order_release);
596 _bool.store(
false, std::memory_order_release);
599 std::atomic<bool>& _bool;
612 std::vector<PyScope> _pyScopes;
615 TRACE_API
static std::atomic<int> _isEnabled;
622 TimeStamp _measuredScopeOverhead;
627#ifndef PXR_PYTHON_SUPPORT_ENABLED
629 ARCH_PRAGMA_UNUSED_PRIVATE_FIELD
631 std::atomic<int> _isPythonTracingEnabled;
632 TfPyTraceFnId _pyTraceFnId;
633#ifndef PXR_PYTHON_SUPPORT_ENABLED
640PXR_NAMESPACE_CLOSE_SCOPE
uint32_t TraceCategoryId
Categories that a TraceReporter can use to filter events.
Manage a single instance of an object (see.
static T & GetInstance()
Return a reference to an object of type T, creating it if necessary.
Enable a concrete base class for use with TfWeakPtr.
This is a singleton class that records TraceEvent instances and populates TraceCollection instances.
TRACE_API void SetEnabled(bool isEnabled)
Enables or disables collection of events for DefaultCategory.
void BeginEventAtTime(const Key &key, double ms)
Record a begin event with key at a specified time if Category is enabled.
bool IsPythonTracingEnabled() const
Returns whether automatic tracing of all python scopes is enabled.
void RecordCounterDelta(const TraceKey &key, double delta)
Record a counter delta for a name key if Category is enabled.
TimeStamp MarkerEvent(const Key &key)
Record a marker event with key if Category is enabled.
void EndEventAtTime(const Key &key, double ms)
Record an end event with key at a specified time if Category is enabled.
void ScopeArgs(Args &&... args)
Record multiple data events with the default category if collection of events is enabled.
TRACE_API void SetPythonTracingEnabled(bool enabled)
Set whether automatic tracing of all python scopes is enabled.
void BeginScope(const TraceKey &_key)
Record a begin event for a scope described by key if Category is enabled.
TimeStamp EndEvent(const Key &key)
Record an end event with key if Category is enabled.
TRACE_API void CreateCollection()
Produces a TraceCollection from all the events that recorded in the collector and issues a TraceColle...
void StoreData(const TraceKey &key, const T &value)
Record a data event with the given key and value 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.
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.
void ScopeArgs(Args &&... args)
Record multiple data events with category cat if Category is enabled.
static bool IsEnabled()
Returns whether collection of events is enabled for DefaultCategory.
TRACE_API void Clear()
Clear all pending events from the collector.
const std::string & GetLabel()
Return the label associated with this collector.
void RecordCounterValue(const TraceKey &key, double value)
Record a counter value for a name key if Category is enabled.
static TRACE_API TraceCollector & GetInstance()
Returns the singleton instance.
TRACE_API TimeStamp GetScopeOverhead() const
Return the overhead cost to measure a scope.
TimeStamp BeginEvent(const Key &key)
Record a begin event with key if Category is enabled.
void RecordCounterValue(const Key &key, double value)
Record a counter value for a name key and delta value 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.
void EndScope(const TraceKey &key)
Record an end event described by 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 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 MarkerEventStatic(const TraceKey &key)
Record a scope event described by key that started at start if Category is enabled.
void RecordCounterDelta(const Key &key, double delta)
Record a counter delta for a name key if Category is enabled.
This class supports thread safe insertion and iteration over a list of items.
This class stores data used to create dynamic keys which can be referenced in TraceEvent instances.
uint64_t TimeStamp
Time in "ticks".
This class represents an ordered collection of TraceEvents and the TraceDynamicKeys and data that the...
A wrapper around a TraceStaticKeyData pointer that is stored in TraceEvent instances.
This class represents an identifier for a thread.
Standard pointer typedefs.
#define TF_DECLARE_WEAK_PTRS(type)
Define standard weak pointer types.
#define TF_DECLARE_WEAK_AND_REF_PTRS(type)
Define standard weak, ref, and vector pointer types.
#define TF_MALLOC_TAG_NEW(name1, name2)
Enable lib/tf memory management.
Pragmas for controlling compiler-specific behaviors.
Manage a single instance of an object.
Structure passed to python trace functions.
Default Trace category which corresponds to events stored for TRACE_ macros.
static constexpr TraceCategoryId GetId()
Returns TraceCategory::Default.
static bool IsEnabled()
Returns the result of TraceCollector::IsEnabled.
Pointer storage with deletion detection.