8#ifndef PXR_BASE_TRACE_COLLECTOR_H
9#define PXR_BASE_TRACE_COLLECTOR_H
13#include "pxr/base/trace/api.h"
14#include "pxr/base/trace/concurrentList.h"
15#include "pxr/base/trace/collection.h"
16#include "pxr/base/trace/event.h"
17#include "pxr/base/trace/key.h"
18#include "pxr/base/trace/threads.h"
23#include "pxr/base/tf/pyTracing.h"
37#include <tbb/spin_mutex.h>
39PXR_NAMESPACE_OPEN_SCOPE
41class TraceScopeHolder;
60 using ThisPtr = TraceCollectorPtr;
78 return (_isEnabled.load(std::memory_order_acquire) == 1);
90#ifdef PXR_PYTHON_SUPPORT_ENABLED
93 return _isPythonTracingEnabled.load(std::memory_order_acquire) != 0;
118 template <
typename Category = DefaultCategory>
120 if (ARCH_LIKELY(!Category::IsEnabled())) {
123 return _BeginEvent(key, Category::GetId());
131 template <
typename Category = DefaultCategory>
133 if (ARCH_LIKELY(!Category::IsEnabled())) {
136 _BeginEventAtTime(key, ms, Category::GetId());
147 template <
typename Category = DefaultCategory>
149 if (ARCH_LIKELY(!Category::IsEnabled())) {
152 return _EndEvent(key, Category::GetId());
160 template <
typename Category = DefaultCategory>
162 if (ARCH_LIKELY(!Category::IsEnabled())) {
165 _EndEventAtTime(key, ms, Category::GetId());
173 template <
typename Category = DefaultCategory>
175 if (ARCH_LIKELY(!Category::IsEnabled())) {
178 return _MarkerEvent(key, Category::GetId());
186 template <
typename Category = DefaultCategory>
188 if (ARCH_LIKELY(!Category::IsEnabled())) {
191 _MarkerEventAtTime(key, ms, Category::GetId());
199 template <
typename Category = DefaultCategory>
201 if (ARCH_LIKELY(!Category::IsEnabled()))
204 _BeginScope(_key, Category::GetId());
212 template <
typename Category,
typename... Args>
214 const TraceKey& key, Args&&... args) {
215 static_assert(
sizeof...(Args) %2 == 0,
216 "Data arguments must come in pairs");
218 if (ARCH_LIKELY(!Category::IsEnabled()))
221 _PerThreadData *threadData = _GetThreadData();
222 threadData->BeginScope(key, Category::GetId());
223 _StoreDataRec(threadData, Category::GetId(), std::forward<Args>(args)...);
230 template <
typename... Args>
232 static_assert(
sizeof...(Args) %2 == 0,
233 "Data arguments must come in pairs");
237 BeginScope<DefaultCategory>(key,
238 std::forward<Args>(args)...);
245 template <
typename Category = DefaultCategory>
247 if (ARCH_LIKELY(!Category::IsEnabled()))
250 _EndScope(key, Category::GetId());
269 template <
typename Category = DefaultCategory>
271 if (ARCH_LIKELY(!Category::IsEnabled()))
273 _PerThreadData *threadData = _GetThreadData();
274 threadData->EmplaceEvent(
275 TraceEvent::Timespan, key, start, stop, Category::GetId());
281 template <
typename Category,
typename... Args>
283 static_assert(
sizeof...(Args) %2 == 0,
284 "Data arguments must come in pairs");
286 if (ARCH_LIKELY(!Category::IsEnabled()))
289 _PerThreadData *threadData = _GetThreadData();
290 _StoreDataRec(threadData, Category::GetId(), std::forward<Args>(args)...);
299 template <
typename... Args>
301 static_assert(
sizeof...(Args) %2 == 0,
302 "Data arguments must come in pairs");
304 ScopeArgs<DefaultCategory>(std::forward<Args>(args)...);
314 template <
typename Category = DefaultCategory>
316 if (ARCH_LIKELY(!Category::IsEnabled()))
319 _PerThreadData *threadData = _GetThreadData();
320 threadData->EmplaceEvent(
321 TraceEvent::Marker, key, Category::GetId());
328 template <
typename Category = DefaultCategory,
typename T>
330 if (ARCH_UNLIKELY(Category::IsEnabled())) {
331 _StoreData(_GetThreadData(), key, Category::GetId(), value);
336 template <
typename Category = DefaultCategory>
340 if (ARCH_UNLIKELY(Category::IsEnabled())) {
341 _PerThreadData *threadData = _GetThreadData();
342 threadData->EmplaceEvent(
343 TraceEvent::CounterDelta, key, delta, Category::GetId());
348 template <
typename Category = DefaultCategory>
350 if (ARCH_UNLIKELY(Category::IsEnabled())) {
351 _PerThreadData *threadData = _GetThreadData();
352 threadData->CounterDelta(key, delta, Category::GetId());
357 template <
typename Category = DefaultCategory>
360 if (ARCH_UNLIKELY(Category::IsEnabled())) {
361 _PerThreadData *threadData = _GetThreadData();
362 threadData->EmplaceEvent(
363 TraceEvent::CounterValue, key, value, Category::GetId());
369 template <
typename Category = DefaultCategory>
372 if (ARCH_UNLIKELY(Category::IsEnabled())) {
373 _PerThreadData *threadData = _GetThreadData();
374 threadData->CounterValue(key, value, Category::GetId());
397 class _PerThreadData;
401 TRACE_API _PerThreadData* _GetThreadData() noexcept;
405 TRACE_API
void _BeginEventAtTime(
410 TRACE_API
void _EndEventAtTime(
415 TRACE_API
void _MarkerEventAtTime(
423 _PerThreadData *threadData = _GetThreadData();
424 threadData->BeginScope(key, cat);
431 TRACE_API
void _MeasureScopeOverhead();
433#ifdef PXR_PYTHON_SUPPORT_ENABLED
439 template <
typename T,
440 typename std::enable_if<
441 sizeof(T) <=
sizeof(uintptr_t)
442 && !std::is_pointer<T>::value ,
int>::type = 0>
443 void _StoreData(_PerThreadData* threadData,
const TraceKey &key,
445 threadData->StoreData(key, value, cat);
449 template <
typename T,
450 typename std::enable_if<
451 (
sizeof(T) >
sizeof(uintptr_t))
452 && !std::is_pointer<T>::value,
int>::type = 0>
453 void _StoreData(_PerThreadData* threadData,
const TraceKey &key,
455 threadData->StoreLargeData(key, value, cat);
460 _PerThreadData* threadData,
464 threadData->StoreLargeData(key, value, cat);
469 _PerThreadData* threadData,
472 const std::string& value) {
473 threadData->StoreLargeData(key, value.c_str(), cat);
477 template <
typename K,
typename T,
typename... Args>
480 const T& value, Args&&... args) {
481 _StoreData(threadData, std::forward<K>(key), cat, value);
482 _StoreDataRec(threadData, cat, std::forward<Args>(args)...);
491 class _PerThreadData {
506 void BeginEventAtTime(
509 void MarkerEventAtTime(
const Key& key,
double ms,
TraceCategoryId cat);
512 AtomicRef lock(_writing);
513 _BeginScope(key, cat);
517 AtomicRef lock(_writing);
521 TRACE_API
void CounterDelta(
524 TRACE_API
void CounterValue(
527 template <
typename T>
530 AtomicRef lock(_writing);
531 _events.load(std::memory_order_acquire)->EmplaceBack(
532 TraceEvent::Data, key, data, cat);
535 template <
typename T>
538 AtomicRef lock(_writing);
539 EventList* events = _events.load(std::memory_order_acquire);
540 const auto* cached = events->StoreData(data);
541 events->EmplaceBack(TraceEvent::Data, key, cached, cat);
544 template <
typename... Args>
545 void EmplaceEvent(Args&&... args) {
546 AtomicRef lock(_writing);
547 _events.load(std::memory_order_acquire)->EmplaceBack(
548 std::forward<Args>(args)...);
551#ifdef PXR_PYTHON_SUPPORT_ENABLED
552 void PushPyScope(
const Key& key,
bool enabled);
553 void PopPyScope(
bool enabled);
558 std::unique_ptr<EventList> GetCollectionData();
563 _events.load(std::memory_order_acquire)->EmplaceBack(
564 TraceEvent::Begin, key, cat);
570 mutable std::atomic<bool> _writing;
571 std::atomic<EventList*> _events;
575 AtomicRef(std::atomic<bool>& b) : _bool(b) {
576 _bool.store(
true, std::memory_order_release);
579 _bool.store(
false, std::memory_order_release);
582 std::atomic<bool>& _bool;
595 std::vector<PyScope> _pyScopes;
598 TRACE_API
static std::atomic<int> _isEnabled;
605 TimeStamp _measuredScopeOverhead;
610#ifndef PXR_PYTHON_SUPPORT_ENABLED
612 ARCH_PRAGMA_UNUSED_PRIVATE_FIELD
614 std::atomic<int> _isPythonTracingEnabled;
615 TfPyTraceFnId _pyTraceFnId;
616#ifndef PXR_PYTHON_SUPPORT_ENABLED
623PXR_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.