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> 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 110 return _isPythonTracingEnabled.load(std::memory_order_acquire) != 0;
115 #endif // PXR_PYTHON_SUPPORT_ENABLED 122 TRACE_API
void Clear();
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());
278 Scope(
const TraceKey& key, TimeStamp start, TimeStamp stop) noexcept;
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 453 #endif // 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 {
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);
571 #endif // PXR_PYTHON_SUPPORT_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 640 PXR_NAMESPACE_CLOSE_SCOPE
642 #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.
Pragmas for controlling compiler-specific behaviors.
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.