1 //
2 // Copyright 2018 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 //    names, trademarks, service marks, or product names of the Licensor
11 //    and its affiliates, except as required to comply with Section 4(c) of
12 //    the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 //     http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 
25 #ifndef PXR_BASE_TRACE_EVENT_H
26 #define PXR_BASE_TRACE_EVENT_H
27 
28 #include "pxr/pxr.h"
29 
30 #include "pxr/base/trace/api.h"
31 #include "pxr/base/trace/category.h"
32 #include "pxr/base/trace/key.h"
33 
34 #include "pxr/base/arch/timing.h"
35 
36 PXR_NAMESPACE_OPEN_SCOPE
37 
38 class TraceEventData;
39 
40 ////////////////////////////////////////////////////////////////////////////////
41 /// \class TraceEvent
42 ///
43 /// This represents an event recorded by a TraceCollector.
44 /// It contains a key (name), categoryId, timestamp, type, and optional
45 /// metadata.
46 ///
47 class TraceEvent {
48 public:
49     /// Time in "ticks".
50     using TimeStamp = uint64_t;
51     using Key = TraceKey;
52 
53     /// \name Tag enums to select constructors
54     /// @{
55     enum BeginTag { Begin };
56     enum EndTag { End };
57     enum TimespanTag { Timespan };
58     enum MarkerTag { Marker };
59     enum CounterDeltaTag { CounterDelta };
60     enum CounterValueTag { CounterValue };
61     enum DataTag { Data };
62     /// @}
63 
64     /// Valid event types
65     enum class EventType : uint8_t {
66         Unknown, ///< The event is an unknown type.
67         Begin, ///< The event represents the beginning timestamp of a scope.
68         End, ///< The event represents the ending timestamp of a scope.
69         Timespan, ///< The event represents begin and end timestamp of a scope.
70         Marker, ///< The event represents an marker without a duration.
71         CounterDelta, ///< The event represents a change in a counter.
72         CounterValue, ///< The event represents the value of a counter.
73         ScopeData,
74         ///< The event stores data that is associated with its enclosing scope.
75     };
76 
77     /// The different types of data that can be stored in a TraceEvent instance.
78     enum class DataType : uint8_t {
79         String, ///< The event is storing a string.
80         Boolean, ///< The event is storing a bool.
81         Int, ///< The event is storing an integer.
82         UInt, ///< The event is storing an unsigned integer.
83         Float, ///< The event is storing an double.
84         Invalid ///< The event is not storing any data.
85     };
86 
87     ///  Return this event's key.
GetKey()88     const Key& GetKey() const { return _key; }
89 
90     ///  Return the time stamp associated with this event.
91     TRACE_API TimeStamp GetTimeStamp() const;
92 
93     ///  Return the counter value associated with this event.
94     TRACE_API double GetCounterValue() const;
95 
96     /// Returns the event's category id.
GetCategory()97     TraceCategoryId GetCategory() const { return _category; }
98 
99     /// Returns the start time of a timespan event.
100     TRACE_API TimeStamp GetStartTimeStamp() const;
101 
102     /// Returns the end time of a timespan event.
103     TRACE_API TimeStamp GetEndTimeStamp() const;
104 
105     /// Returns the data stored in a data event.
106     TRACE_API TraceEventData GetData() const;
107 
108     /// Returns the type of the event.
109     TRACE_API EventType GetType() const;
110 
111     /// \name Constructors
112     /// @{
113 
114     /// Constructor for Begin events that will automatically set the
115     /// timestamp from the current time.
TraceEvent(BeginTag,const Key & key,TraceCategoryId cat)116     TraceEvent(BeginTag, const Key& key, TraceCategoryId cat) :
117         _key(key),
118         _category(cat),
119         _type(_InternalEventType::Begin),
120         _time(ArchGetTickTime()) {
121     }
122 
123     /// Constructor for Begin events that takes a specific TimeStamp \a ts.
TraceEvent(BeginTag,const Key & key,TimeStamp ts,TraceCategoryId cat)124     TraceEvent( BeginTag,
125                 const Key& key,
126                 TimeStamp ts,
127                 TraceCategoryId cat) :
128         _key(key),
129         _category(cat),
130         _type(_InternalEventType::Begin),
131         _time(ts) {
132     }
133 
134     /// Constructor for End events that will automatically set the
135     /// timestamp from the current time.
TraceEvent(EndTag,const Key & key,TraceCategoryId cat)136     TraceEvent(EndTag, const Key& key, TraceCategoryId cat) :
137         _key(key),
138         _category(cat),
139         _type(_InternalEventType::End),
140         _time(ArchGetTickTime()) {
141     }
142 
143     /// Constructor for End events that takes a specific TimeStamp \a ts.
TraceEvent(EndTag,const Key & key,TimeStamp ts,TraceCategoryId cat)144     TraceEvent( EndTag,
145                 const Key& key,
146                 TimeStamp ts,
147                 TraceCategoryId cat) :
148         _key(key),
149         _category(cat),
150         _type(_InternalEventType::End),
151         _time(ts) {
152     }
153 
154     /// Constructor for Timespan events that takes a TimeStamp \a starttime
155     /// and automatically sets the end timestamp from the current time.
TraceEvent(TimespanTag,const Key & key,TimeStamp startTime,TraceCategoryId cat)156     TraceEvent(
157         TimespanTag, const Key& key, TimeStamp startTime, TraceCategoryId cat) :
158         _key(key),
159         _category(cat),
160         _type(_InternalEventType::Timespan),
161         _time(ArchGetTickTime()) {
162         new (&_payload) TimeStamp(startTime);
163     }
164 
165     /// Constructor for Timespan events that takes the start time and end time.
TraceEvent(TimespanTag,const Key & key,TimeStamp startTime,TimeStamp endTime,TraceCategoryId cat)166     TraceEvent(
167         TimespanTag, const Key& key,
168         TimeStamp startTime, TimeStamp endTime,
169         TraceCategoryId cat) :
170         _key(key),
171         _category(cat),
172         _type(_InternalEventType::Timespan),
173         _time(endTime) {
174         new (&_payload) TimeStamp(startTime);
175     }
176 
177     /// Constructor for Marker events that will automatically set the
178     /// timestamp from the current time.
TraceEvent(MarkerTag,const Key & key,TraceCategoryId cat)179     TraceEvent(MarkerTag, const Key& key, TraceCategoryId cat) :
180         _key(key),
181         _category(cat),
182         _type(_InternalEventType::Marker),
183         _time(ArchGetTickTime()) {
184     }
185 
186     /// Constructor for Mark events that takes a specific TimeStamp \a ts.
TraceEvent(MarkerTag,const Key & key,TimeStamp ts,TraceCategoryId cat)187     TraceEvent( MarkerTag,
188                 const Key& key,
189                 TimeStamp ts,
190                 TraceCategoryId cat) :
191         _key(key),
192         _category(cat),
193         _type(_InternalEventType::Marker),
194         _time(ts) {
195     }
196 
197     /// Constructor for Counter delta events.
TraceEvent(CounterDeltaTag,const Key & key,double value,TraceCategoryId cat)198     TraceEvent( CounterDeltaTag,
199                 const Key& key,
200                 double value,
201                 TraceCategoryId cat) :
202         _key(key),
203         _category(cat),
204         _type(_InternalEventType::CounterDelta),
205         _time(ArchGetTickTime()) {
206         new (&_payload) double(value);
207     }
208 
209     /// Constructor for Counter value events.
TraceEvent(CounterValueTag,const Key & key,double value,TraceCategoryId cat)210     TraceEvent( CounterValueTag,
211                 const Key& key,
212                 double value,
213                 TraceCategoryId cat) :
214         _key(key),
215         _category(cat),
216         _type(_InternalEventType::CounterValue),
217         _time(ArchGetTickTime()) {
218         new (&_payload) double(value);
219     }
220 
221     /// \name Constructors for data events
222     /// @{
TraceEvent(DataTag,const Key & key,bool data,TraceCategoryId cat)223     TraceEvent(DataTag, const Key& key, bool data, TraceCategoryId cat) :
224         _key(key),
225         _category(cat),
226         _dataType(DataType::Boolean),
227         _type(_InternalEventType::ScopeData),
228         _time(ArchGetTickTime()) {
229         new (&_payload) bool(data);
230     }
231 
TraceEvent(DataTag,const Key & key,int data,TraceCategoryId cat)232     TraceEvent(DataTag, const Key& key, int data, TraceCategoryId cat) :
233         _key(key),
234         _category(cat),
235         _dataType(DataType::Int),
236         _type(_InternalEventType::ScopeData),
237         _time(ArchGetTickTime()) {
238         new (&_payload) int64_t(data);
239     }
240 
TraceEvent(DataTag,const Key & key,int64_t data,TraceCategoryId cat)241     TraceEvent(DataTag, const Key& key, int64_t data, TraceCategoryId cat) :
242         _key(key),
243         _category(cat),
244         _dataType(DataType::Int),
245         _type(_InternalEventType::ScopeData),
246         _time(ArchGetTickTime()) {
247         new (&_payload) int64_t(data);
248     }
249 
TraceEvent(DataTag,const Key & key,uint64_t data,TraceCategoryId cat)250     TraceEvent(DataTag, const Key& key, uint64_t data, TraceCategoryId cat) :
251         _key(key),
252         _category(cat),
253         _dataType(DataType::UInt),
254         _type(_InternalEventType::ScopeData),
255         _time(ArchGetTickTime()) {
256         new (&_payload) uint64_t(data);
257     }
258 
TraceEvent(DataTag,const Key & key,double data,TraceCategoryId cat)259     TraceEvent(DataTag, const Key& key, double data, TraceCategoryId cat) :
260         _key(key),
261         _category(cat),
262         _dataType(DataType::Float),
263         _type(_InternalEventType::ScopeData),
264         _time(ArchGetTickTime()) {
265         new (&_payload) double(data);
266     }
267 
TraceEvent(DataTag,const Key & key,const char * data,TraceCategoryId cat)268     TraceEvent(DataTag, const Key& key, const char* data, TraceCategoryId cat) :
269         _key(key),
270         _category(cat),
271         _dataType(DataType::String),
272         _type(_InternalEventType::ScopeDataLarge),
273         _time(ArchGetTickTime()) {
274         new (&_payload) const char*(data);
275     }
276     /// @}
277 
278     // Can move this, but not copy it
279     TraceEvent(const TraceEvent&) = delete;
280     TraceEvent& operator= (const TraceEvent&) = delete;
281 
282     TraceEvent(TraceEvent&&) = default;
283     TraceEvent& operator= (TraceEvent&&) = default;
284 
285     /// @}
286 
287     /// Sets the events timestamp to \p time.
SetTimeStamp(TimeStamp time)288     void SetTimeStamp(TimeStamp time) { _time = time; }
289 private:
290     // Valid event types. This type has more detail that the public facing
291     // EventType enum.
292     enum class _InternalEventType : uint8_t {
293         Begin,
294         End,
295         Timespan,
296         Marker,
297         CounterDelta,
298         CounterValue,
299         ScopeData,
300         ScopeDataLarge,
301     };
302 
303     using PayloadStorage = std::aligned_storage<8, 8>::type;
304 
305     Key _key;
306     TraceCategoryId _category;
307     DataType _dataType;
308     _InternalEventType _type;
309     TimeStamp _time;
310     PayloadStorage _payload;
311 };
312 
313 PXR_NAMESPACE_CLOSE_SCOPE
314 
315 #endif // PXR_BASE_TRACE_EVENT_H
316