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 #ifdef PXR_PYTHON_SUPPORT_ENABLED
41 #include "pxr/base/tf/pyTracing.h"
42 #endif // PXR_PYTHON_SUPPORT_ENABLED
54 #include <tbb/spin_mutex.h>
56 PXR_NAMESPACE_OPEN_SCOPE
58 class TraceScopeHolder;
74 TF_MALLOC_TAG_NEW(
"Trace",
"TraceCollector");
77 using ThisPtr = TraceCollectorPtr;
95 return (_isEnabled.load(std::memory_order_acquire) == 1);
107 #ifdef PXR_PYTHON_SUPPORT_ENABLED
108 bool IsPythonTracingEnabled()
const {
110 return _isPythonTracingEnabled.load(std::memory_order_acquire) != 0;
114 TRACE_API
void SetPythonTracingEnabled(
bool enabled);
115 #endif // PXR_PYTHON_SUPPORT_ENABLED
119 TRACE_API
void Clear();
132 template <
typename Category = DefaultCategory>
134 if (ARCH_LIKELY(!Category::IsEnabled())) {
137 return _BeginEvent(key, Category::GetId());
145 template <
typename Category = DefaultCategory>
147 if (ARCH_LIKELY(!Category::IsEnabled())) {
150 _BeginEventAtTime(key, ms, Category::GetId());
161 template <
typename Category = DefaultCategory>
163 if (ARCH_LIKELY(!Category::IsEnabled())) {
166 return _EndEvent(key, Category::GetId());
174 template <
typename Category = DefaultCategory>
176 if (ARCH_LIKELY(!Category::IsEnabled())) {
179 _EndEventAtTime(key, ms, Category::GetId());
187 template <
typename Category = DefaultCategory>
189 if (ARCH_LIKELY(!Category::IsEnabled())) {
192 return _MarkerEvent(key, Category::GetId());
200 template <
typename Category = DefaultCategory>
202 if (ARCH_LIKELY(!Category::IsEnabled())) {
205 _MarkerEventAtTime(key, ms, Category::GetId());
213 template <
typename Category = DefaultCategory>
215 if (ARCH_LIKELY(!Category::IsEnabled()))
218 _BeginScope(_key, Category::GetId());
226 template <
typename Category,
typename... Args>
228 const TraceKey& key, Args&&... args) {
229 static_assert(
sizeof...(Args) %2 == 0,
230 "Data arguments must come in pairs");
232 if (ARCH_LIKELY(!Category::IsEnabled()))
235 _PerThreadData *threadData = _GetThreadData();
236 threadData->BeginScope(key, Category::GetId());
237 _StoreDataRec(threadData, Category::GetId(), std::forward<Args>(args)...);
244 template <
typename... Args>
246 static_assert(
sizeof...(Args) %2 == 0,
247 "Data arguments must come in pairs");
251 BeginScope<DefaultCategory>(key,
252 std::forward<Args>(args)...);
259 template <
typename Category = DefaultCategory>
261 if (ARCH_LIKELY(!Category::IsEnabled()))
264 _EndScope(key, Category::GetId());
273 template <
typename Category = DefaultCategory>
275 if (ARCH_LIKELY(!Category::IsEnabled()))
278 _PerThreadData *threadData = _GetThreadData();
279 threadData->EmplaceEvent(
280 TraceEvent::Timespan, key, start, Category::GetId());
286 template <
typename Category,
typename... Args>
288 static_assert(
sizeof...(Args) %2 == 0,
289 "Data arguments must come in pairs");
291 if (ARCH_LIKELY(!Category::IsEnabled()))
294 _PerThreadData *threadData = _GetThreadData();
295 _StoreDataRec(threadData, Category::GetId(), std::forward<Args>(args)...);
304 template <
typename... Args>
306 static_assert(
sizeof...(Args) %2 == 0,
307 "Data arguments must come in pairs");
309 ScopeArgs<DefaultCategory>(std::forward<Args>(args)...);
319 template <
typename Category = DefaultCategory>
321 if (ARCH_LIKELY(!Category::IsEnabled()))
324 _PerThreadData *threadData = _GetThreadData();
325 threadData->EmplaceEvent(
326 TraceEvent::Marker, key, Category::GetId());
333 template <
typename Category = DefaultCategory,
typename T>
335 if (ARCH_UNLIKELY(Category::IsEnabled())) {
336 _StoreData(_GetThreadData(), key, Category::GetId(), value);
341 template <
typename Category = DefaultCategory>
345 if (ARCH_UNLIKELY(Category::IsEnabled())) {
346 _PerThreadData *threadData = _GetThreadData();
347 threadData->EmplaceEvent(
348 TraceEvent::CounterDelta, key, delta, Category::GetId());
353 template <
typename Category = DefaultCategory>
355 if (ARCH_UNLIKELY(Category::IsEnabled())) {
356 _PerThreadData *threadData = _GetThreadData();
357 threadData->CounterDelta(key, delta, Category::GetId());
362 template <
typename Category = DefaultCategory>
365 if (ARCH_UNLIKELY(Category::IsEnabled())) {
366 _PerThreadData *threadData = _GetThreadData();
367 threadData->EmplaceEvent(
368 TraceEvent::CounterValue, key, value, Category::GetId());
374 template <
typename Category = DefaultCategory>
377 if (ARCH_UNLIKELY(Category::IsEnabled())) {
378 _PerThreadData *threadData = _GetThreadData();
379 threadData->CounterValue(key, value, Category::GetId());
402 class _PerThreadData;
406 TRACE_API _PerThreadData* _GetThreadData();
410 TRACE_API
void _BeginEventAtTime(
415 TRACE_API
void _EndEventAtTime(
420 TRACE_API
void _MarkerEventAtTime(
428 _PerThreadData *threadData = _GetThreadData();
429 threadData->BeginScope(key, cat);
436 #ifdef PXR_PYTHON_SUPPORT_ENABLED
439 #endif // PXR_PYTHON_SUPPORT_ENABLED
442 template <
typename T,
443 typename std::enable_if<
444 sizeof(T) <=
sizeof(uintptr_t)
445 && !std::is_pointer<T>::value ,
int>::type = 0>
446 void _StoreData(_PerThreadData* threadData,
const TraceKey &key,
448 threadData->StoreData(key, value, cat);
452 template <
typename T,
453 typename std::enable_if<
454 (
sizeof(T) >
sizeof(uintptr_t))
455 && !std::is_pointer<T>::value,
int>::type = 0>
456 void _StoreData(_PerThreadData* threadData,
const TraceKey &key,
458 threadData->StoreLargeData(key, value, cat);
463 _PerThreadData* threadData,
467 threadData->StoreLargeData(key, value, cat);
472 _PerThreadData* threadData,
475 const std::string& value) {
476 threadData->StoreLargeData(key, value.c_str(), cat);
480 template <
typename K,
typename T,
typename... Args>
483 const T& value, Args&&... args) {
484 _StoreData(threadData, std::forward<K>(key), cat, value);
485 _StoreDataRec(threadData, cat, std::forward<Args>(args)...);
494 class _PerThreadData {
501 const TraceThreadId& GetThreadId()
const {
515 AtomicRef lock(_writing);
516 _BeginScope(key, cat);
520 AtomicRef lock(_writing);
524 TRACE_API
void CounterDelta(
527 TRACE_API
void CounterValue(
530 template <
typename T>
533 AtomicRef lock(_writing);
534 _events.load(std::memory_order_acquire)->EmplaceBack(
535 TraceEvent::Data, key, data, cat);
538 template <
typename T>
541 AtomicRef lock(_writing);
542 EventList* events = _events.load(std::memory_order_acquire);
543 const auto* cached = events->StoreData(data);
544 events->EmplaceBack(TraceEvent::Data, key, cached, cat);
547 template <
typename... Args>
548 void EmplaceEvent(Args&&... args) {
549 AtomicRef lock(_writing);
550 _events.load(std::memory_order_acquire)->EmplaceBack(
551 std::forward<Args>(args)...);
554 #ifdef PXR_PYTHON_SUPPORT_ENABLED
555 void PushPyScope(
const Key& key,
bool enabled);
556 void PopPyScope(
bool enabled);
557 #endif // PXR_PYTHON_SUPPORT_ENABLED
561 std::unique_ptr<EventList> GetCollectionData();
566 _events.load(std::memory_order_acquire)->EmplaceBack(
567 TraceEvent::Begin, key, cat);
573 mutable std::atomic<bool> _writing;
574 std::atomic<EventList*> _events;
578 AtomicRef(std::atomic<bool>& b) : _bool(b) {
579 _bool.store(
true, std::memory_order_release);
582 _bool.store(
false, std::memory_order_release);
585 std::atomic<bool>& _bool;
592 TraceThreadId _threadIndex;
594 #ifdef PXR_PYTHON_SUPPORT_ENABLED
599 std::vector<PyScope> _pyScopes;
600 #endif // PXR_PYTHON_SUPPORT_ENABLED
603 TRACE_API
static std::atomic<int> _isEnabled;
610 #ifdef PXR_PYTHON_SUPPORT_ENABLED
611 std::atomic<int> _isPythonTracingEnabled;
612 TfPyTraceFnId _pyTraceFnId;
613 #endif // PXR_PYTHON_SUPPORT_ENABLED
618 PXR_NAMESPACE_CLOSE_SCOPE
620 #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.
uint64_t TimeStamp
Time in "ticks".
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 RecordCounterValue(const TraceKey &key, double value)
Record a counter value for a name key if Category 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.
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 ScopeArgs(Args &&...args)
Record multiple data events with category cat 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...
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 Scope(const TraceKey &key, TimeStamp start)
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.
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.
This class represents an ordered collection of TraceEvents and the TraceDynamicKeys and data that the...
void ScopeArgs(Args &&...args)
Record multiple data events with the default category if collection of events is enabled.
static bool IsEnabled()
Returns whether collection of events is enabled for DefaultCategory.
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.
A wrapper around a TraceStaticKeyData pointer that is stored in TraceEvent instances.