• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef INCLUDE_PERFETTO_TRACING_TRACK_EVENT_LEGACY_H_
18 #define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_LEGACY_H_
19 
20 // This file defines a compatibility shim between legacy (Chrome, V8) trace
21 // event macros and track events. To avoid accidentally introducing legacy
22 // events in new code, the PERFETTO_ENABLE_LEGACY_TRACE_EVENTS macro must be set
23 // to 1 activate the compatibility layer.
24 
25 #include "perfetto/base/compiler.h"
26 #include "perfetto/tracing/track_event.h"
27 
28 #include <stdint.h>
29 
30 #ifndef PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
31 #define PERFETTO_ENABLE_LEGACY_TRACE_EVENTS 0
32 #endif
33 
34 // Ignore GCC warning about a missing argument for a variadic macro parameter.
35 #if defined(__GNUC__) || defined(__clang__)
36 #pragma GCC system_header
37 #endif
38 
39 // ----------------------------------------------------------------------------
40 // Internal legacy trace point implementation.
41 // ----------------------------------------------------------------------------
42 
43 namespace perfetto {
44 namespace legacy {
45 
46 // The following user-provided adaptors are used to serialize user-defined
47 // thread id and time types into track events. For full compatibility, the user
48 // should also define the following macros appropriately:
49 //
50 //   #define TRACE_TIME_TICKS_NOW() ...
51 //   #define TRACE_TIME_NOW() ...
52 
53 // User-provided function to convert an abstract thread id into a thread track.
54 template <typename T>
55 ThreadTrack ConvertThreadId(const T&);
56 
57 // Built-in implementation for events referring to the current thread.
58 template <>
59 ThreadTrack PERFETTO_EXPORT_COMPONENT
60 ConvertThreadId(const PerfettoLegacyCurrentThreadId&);
61 
62 }  // namespace legacy
63 }  // namespace perfetto
64 
65 #if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
66 
67 // Implementations for the INTERNAL_* adapter macros used by the trace points
68 // below.
69 #define PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(phase, category, name, track, \
70                                                 ...)                          \
71   PERFETTO_INTERNAL_TRACK_EVENT(                                              \
72       category, ::perfetto::internal::DecayEventNameType(name),               \
73       ::perfetto::internal::TrackEventLegacy::PhaseToType(phase), track,      \
74       ##__VA_ARGS__);
75 
76 #define PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(              \
77     phase, category, name, track, flags, ...)                            \
78   PERFETTO_INTERNAL_LEGACY_TRACK_EVENT(                                  \
79       category, ::perfetto::internal::DecayEventNameType(name),          \
80       ::perfetto::internal::TrackEventLegacy::PhaseToType(phase), track, \
81       phase, flags, ##__VA_ARGS__);
82 
83 #define PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                 \
84     phase, category, name, track, flags, thread_id, id, ...)             \
85   PERFETTO_INTERNAL_LEGACY_TRACK_EVENT_WITH_ID(                          \
86       category, ::perfetto::internal::DecayEventNameType(name),          \
87       ::perfetto::internal::TrackEventLegacy::PhaseToType(phase), track, \
88       phase, flags, thread_id, id, ##__VA_ARGS__);
89 
90 // The main entrypoint for writing unscoped legacy events.  This macro
91 // determines the right track to write the event on based on |flags| and
92 // |thread_id|.
93 #define PERFETTO_INTERNAL_LEGACY_EVENT(phase, category, name, flags,       \
94                                        thread_id, ...)                     \
95   [&]() {                                                                  \
96     using ::perfetto::internal::TrackEventInternal;                        \
97     PERFETTO_DCHECK(!(flags & TRACE_EVENT_FLAG_COPY));                     \
98     /* First check the scope for instant events. */                        \
99     if ((phase) == TRACE_EVENT_PHASE_INSTANT) {                            \
100       /* Note: Avoids the need to set LegacyEvent::instant_event_scope. */ \
101       auto scope = (flags)&TRACE_EVENT_FLAG_SCOPE_MASK;                    \
102       switch (scope) {                                                     \
103         case TRACE_EVENT_SCOPE_GLOBAL:                                     \
104           PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(              \
105               phase, category, name, ::perfetto::Track::Global(0), flags,  \
106               ##__VA_ARGS__);                                              \
107           return;                                                          \
108         case TRACE_EVENT_SCOPE_PROCESS:                                    \
109           PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(              \
110               phase, category, name, ::perfetto::ProcessTrack::Current(),  \
111               flags, ##__VA_ARGS__);                                       \
112           return;                                                          \
113         default:                                                           \
114         case TRACE_EVENT_SCOPE_THREAD:                                     \
115           /* Fallthrough. */                                               \
116           break;                                                           \
117       }                                                                    \
118     }                                                                      \
119     /* If an event targets the current thread or another process, write    \
120      * it on the current thread's track. The process override case is      \
121      * handled through |pid_override| in WriteLegacyEvent. */              \
122     if (std::is_same<                                                      \
123             decltype(thread_id),                                           \
124             ::perfetto::legacy::PerfettoLegacyCurrentThreadId>::value ||   \
125         ((flags)&TRACE_EVENT_FLAG_HAS_PROCESS_ID)) {                       \
126       PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(                  \
127           phase, category, name, TrackEventInternal::kDefaultTrack, flags, \
128           ##__VA_ARGS__);                                                  \
129     } else {                                                               \
130       PERFETTO_INTERNAL_LEGACY_EVENT_WITH_FLAGS_ON_TRACK(                  \
131           phase, category, name,                                           \
132           ::perfetto::legacy::ConvertThreadId(thread_id), flags,           \
133           ##__VA_ARGS__);                                                  \
134     }                                                                      \
135   }()
136 
137 #define PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID(phase, category, name, flags, \
138                                                thread_id, id, ...)           \
139   [&]() {                                                                    \
140     using ::perfetto::internal::TrackEventInternal;                          \
141     PERFETTO_DCHECK(!(flags & TRACE_EVENT_FLAG_COPY));                       \
142     /* First check the scope for instant events. */                          \
143     if ((phase) == TRACE_EVENT_PHASE_INSTANT) {                              \
144       /* Note: Avoids the need to set LegacyEvent::instant_event_scope. */   \
145       auto scope = (flags)&TRACE_EVENT_FLAG_SCOPE_MASK;                      \
146       switch (scope) {                                                       \
147         case TRACE_EVENT_SCOPE_GLOBAL:                                       \
148           PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                   \
149               phase, category, name, ::perfetto::Track::Global(0), flags,    \
150               thread_id, id, ##__VA_ARGS__);                                 \
151           return;                                                            \
152         case TRACE_EVENT_SCOPE_PROCESS:                                      \
153           PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                   \
154               phase, category, name, ::perfetto::ProcessTrack::Current(),    \
155               flags, thread_id, id, ##__VA_ARGS__);                          \
156           return;                                                            \
157         default:                                                             \
158         case TRACE_EVENT_SCOPE_THREAD:                                       \
159           /* Fallthrough. */                                                 \
160           break;                                                             \
161       }                                                                      \
162     }                                                                        \
163     /* If an event targets the current thread or another process, write      \
164      * it on the current thread's track. The process override case is        \
165      * handled through |pid_override| in WriteLegacyEvent. */                \
166     if (std::is_same<                                                        \
167             decltype(thread_id),                                             \
168             ::perfetto::legacy::PerfettoLegacyCurrentThreadId>::value ||     \
169         ((flags)&TRACE_EVENT_FLAG_HAS_PROCESS_ID)) {                         \
170       PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                       \
171           phase, category, name, TrackEventInternal::kDefaultTrack, flags,   \
172           thread_id, id, ##__VA_ARGS__);                                     \
173     } else {                                                                 \
174       PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID_ON_TRACK(                       \
175           phase, category, name,                                             \
176           ::perfetto::legacy::ConvertThreadId(thread_id), flags, thread_id,  \
177           id, ##__VA_ARGS__);                                                \
178     }                                                                        \
179   }()
180 
181 #define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...)           \
182   PERFETTO_INTERNAL_LEGACY_EVENT(                                             \
183       phase, category, ::perfetto::internal::DecayEventNameType(name), flags, \
184       ::perfetto::legacy::kCurrentThreadId, ##__VA_ARGS__)
185 
186 #define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...) \
187   PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(                      \
188       category, ::perfetto::internal::DecayEventNameType(name), ##__VA_ARGS__)
189 
190 #define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category, name, bind_id, \
191                                                   flags, ...)              \
192   PERFETTO_INTERNAL_SCOPED_LEGACY_TRACK_EVENT_WITH_ID(                     \
193       category, ::perfetto::internal::DecayEventNameType(name),            \
194       ::perfetto::internal::TrackEventInternal::kDefaultTrack, flags,      \
195       TRACE_EVENT_API_CURRENT_THREAD_ID, bind_id, ##__VA_ARGS__)
196 
197 #define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category, name,        \
198                                                 timestamp, flags, ...)        \
199   PERFETTO_INTERNAL_LEGACY_EVENT(                                             \
200       phase, category, ::perfetto::internal::DecayEventNameType(name), flags, \
201       ::perfetto::legacy::kCurrentThreadId, timestamp, ##__VA_ARGS__)
202 
203 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                   \
204     phase, category, name, id, thread_id, timestamp, flags, ...)              \
205   PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID(                                     \
206       phase, category, ::perfetto::internal::DecayEventNameType(name), flags, \
207       thread_id, id, timestamp, ##__VA_ARGS__)
208 
209 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags,    \
210                                          ...)                                 \
211   PERFETTO_INTERNAL_LEGACY_EVENT_WITH_ID(                                     \
212       phase, category, ::perfetto::internal::DecayEventNameType(name), flags, \
213       ::perfetto::legacy::kCurrentThreadId, id, ##__VA_ARGS__)
214 
215 #define INTERNAL_TRACE_EVENT_METADATA_ADD(category, name, ...)         \
216   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_METADATA, category, name, \
217                            TRACE_EVENT_FLAG_NONE)
218 
219 // ----------------------------------------------------------------------------
220 // Legacy tracing common API (adapted from trace_event_common.h).
221 // ----------------------------------------------------------------------------
222 
223 #define TRACE_DISABLED_BY_DEFAULT(name) "disabled-by-default-" name
224 
225 // Scoped events.
226 #define TRACE_EVENT0(category_group, name) \
227   INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name)
228 #define TRACE_EVENT_WITH_FLOW0(category_group, name, bind_id, flow_flags)  \
229   INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, bind_id, \
230                                             flow_flags)
231 #define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
232   INTERNAL_TRACE_EVENT_ADD_SCOPED(                              \
233       category_group, name, arg1_name,                          \
234       ::perfetto::internal::PossiblyNull(arg1_val))
235 #define TRACE_EVENT_WITH_FLOW1(category_group, name, bind_id, flow_flags, \
236                                arg1_name, arg1_val)                       \
237   INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(                              \
238       category_group, name, bind_id, flow_flags, arg1_name,               \
239       ::perfetto::internal::PossiblyNull(arg1_val))
240 #define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, \
241                      arg2_val)                                             \
242   INTERNAL_TRACE_EVENT_ADD_SCOPED(                                         \
243       category_group, name, arg1_name,                                     \
244       ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,             \
245       ::perfetto::internal::PossiblyNull(arg2_val))
246 #define TRACE_EVENT_WITH_FLOW2(category_group, name, bind_id, flow_flags, \
247                                arg1_name, arg1_val, arg2_name, arg2_val)  \
248   INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(                              \
249       category_group, name, bind_id, flow_flags, arg1_name,               \
250       ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,            \
251       ::perfetto::internal::PossiblyNull(arg2_val))
252 
253 // Instant events.
254 #define TRACE_EVENT_INSTANT0(category_group, name, scope)                   \
255   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
256                            TRACE_EVENT_FLAG_NONE | scope)
257 #define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \
258   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
259                            TRACE_EVENT_FLAG_NONE | scope, arg1_name,           \
260                            ::perfetto::internal::PossiblyNull(arg1_val))
261 #define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \
262                              arg2_name, arg2_val)                              \
263   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
264                            TRACE_EVENT_FLAG_NONE | scope, arg1_name,           \
265                            ::perfetto::internal::PossiblyNull(arg1_val),       \
266                            arg2_name,                                          \
267                            ::perfetto::internal::PossiblyNull(arg2_val))
268 #define TRACE_EVENT_COPY_INSTANT0(category_group, name, scope)        \
269   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, \
270                            ::perfetto::DynamicString{name}, scope)
271 #define TRACE_EVENT_COPY_INSTANT1(category_group, name, scope, arg1_name, \
272                                   arg1_val)                               \
273   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group,     \
274                            ::perfetto::DynamicString{name}, scope,        \
275                            ::perfetto::DynamicString{arg1_name},          \
276                            ::perfetto::internal::PossiblyNull(arg1_val))
277 #define TRACE_EVENT_COPY_INSTANT2(category_group, name, scope, arg1_name, \
278                                   arg1_val, arg2_name, arg2_val)          \
279   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group,     \
280                            ::perfetto::DynamicString{name}, scope,        \
281                            ::perfetto::DynamicString{arg1_name},          \
282                            ::perfetto::internal::PossiblyNull(arg1_val),  \
283                            ::perfetto::DynamicString{arg2_name},          \
284                            ::perfetto::internal::PossiblyNull(arg2_val))
285 #define TRACE_EVENT_INSTANT_WITH_FLAGS0(category_group, name, scope_and_flags) \
286   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
287                            scope_and_flags)
288 #define TRACE_EVENT_INSTANT_WITH_FLAGS1(category_group, name, scope_and_flags, \
289                                         arg1_name, arg1_val)                   \
290   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
291                            scope_and_flags, arg1_name,                         \
292                            ::perfetto::internal::PossiblyNull(arg1_val))
293 
294 // Instant events with explicit timestamps.
295 #define TRACE_EVENT_INSTANT_WITH_TIMESTAMP0(category_group, name, scope,   \
296                                             timestamp)                     \
297   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(TRACE_EVENT_PHASE_INSTANT,       \
298                                           category_group, name, timestamp, \
299                                           TRACE_EVENT_FLAG_NONE | scope)
300 
301 #define TRACE_EVENT_INSTANT_WITH_TIMESTAMP1(category_group, name, scope,  \
302                                             timestamp, arg_name, arg_val) \
303   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                \
304       TRACE_EVENT_PHASE_INSTANT, category_group, name, timestamp,         \
305       TRACE_EVENT_FLAG_NONE | scope, arg_name,                            \
306       ::perfetto::internal::PossiblyNull(arg_val))
307 
308 // Begin events.
309 #define TRACE_EVENT_BEGIN0(category_group, name)                          \
310   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
311                            TRACE_EVENT_FLAG_NONE)
312 #define TRACE_EVENT_BEGIN1(category_group, name, arg1_name, arg1_val)     \
313   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
314                            TRACE_EVENT_FLAG_NONE, arg1_name,              \
315                            ::perfetto::internal::PossiblyNull(arg1_val))
316 #define TRACE_EVENT_BEGIN2(category_group, name, arg1_name, arg1_val,       \
317                            arg2_name, arg2_val)                             \
318   INTERNAL_TRACE_EVENT_ADD(                                                 \
319       TRACE_EVENT_PHASE_BEGIN, category_group, name, TRACE_EVENT_FLAG_NONE, \
320       arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,   \
321       ::perfetto::internal::PossiblyNull(arg2_val))
322 #define TRACE_EVENT_BEGIN_WITH_FLAGS0(category_group, name, flags) \
323   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, flags)
324 #define TRACE_EVENT_BEGIN_WITH_FLAGS1(category_group, name, flags, arg1_name, \
325                                       arg1_val)                               \
326   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name,     \
327                            flags, arg1_name,                                  \
328                            ::perfetto::internal::PossiblyNull(arg1_val))
329 #define TRACE_EVENT_COPY_BEGIN2(category_group, name, arg1_name, arg1_val, \
330                                 arg2_name, arg2_val)                       \
331   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group,        \
332                            ::perfetto::DynamicString{name},                \
333                            TRACE_EVENT_FLAG_NONE,                          \
334                            ::perfetto::DynamicString{arg1_name},           \
335                            ::perfetto::internal::PossiblyNull(arg1_val),   \
336                            ::perfetto::DynamicString{arg2_name},           \
337                            ::perfetto::internal::PossiblyNull(arg2_val))
338 
339 // Begin events with explicit timestamps.
340 #define TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(category_group, name, id, \
341                                                      thread_id, timestamp)     \
342   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
343       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id,      \
344       timestamp, TRACE_EVENT_FLAG_NONE)
345 #define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(       \
346     category_group, name, id, thread_id, timestamp)              \
347   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(            \
348       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,             \
349       ::perfetto::DynamicString{name}, id, thread_id, timestamp, \
350       TRACE_EVENT_FLAG_NONE)
351 #define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP1(               \
352     category_group, name, id, thread_id, timestamp, arg1_name, arg1_val) \
353   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                    \
354       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                     \
355       ::perfetto::DynamicString{name}, id, thread_id, timestamp,         \
356       TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},       \
357       ::perfetto::internal::PossiblyNull(arg1_val))
358 #define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP2(               \
359     category_group, name, id, thread_id, timestamp, arg1_name, arg1_val, \
360     arg2_name, arg2_val)                                                 \
361   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                    \
362       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                     \
363       ::perfetto::DynamicString{name}, id, thread_id, timestamp,         \
364       TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},       \
365       ::perfetto::internal::PossiblyNull(arg1_val),                      \
366       ::perfetto::DynamicString{arg2_name},                              \
367       ::perfetto::internal::PossiblyNull(arg2_val))
368 
369 // End events.
370 #define TRACE_EVENT_END0(category_group, name)                          \
371   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
372                            TRACE_EVENT_FLAG_NONE)
373 #define TRACE_EVENT_END1(category_group, name, arg1_name, arg1_val)     \
374   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
375                            TRACE_EVENT_FLAG_NONE, arg1_name,            \
376                            ::perfetto::internal::PossiblyNull(arg1_val))
377 #define TRACE_EVENT_END2(category_group, name, arg1_name, arg1_val, arg2_name, \
378                          arg2_val)                                             \
379   INTERNAL_TRACE_EVENT_ADD(                                                    \
380       TRACE_EVENT_PHASE_END, category_group, name, TRACE_EVENT_FLAG_NONE,      \
381       arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,      \
382       ::perfetto::internal::PossiblyNull(arg2_val))
383 #define TRACE_EVENT_END_WITH_FLAGS0(category_group, name, flags) \
384   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, flags)
385 #define TRACE_EVENT_END_WITH_FLAGS1(category_group, name, flags, arg1_name,    \
386                                     arg1_val)                                  \
387   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, flags, \
388                            arg1_name,                                          \
389                            ::perfetto::internal::PossiblyNull(arg1_val))
390 #define TRACE_EVENT_COPY_END2(category_group, name, arg1_name, arg1_val,      \
391                               arg2_name, arg2_val)                            \
392   INTERNAL_TRACE_EVENT_ADD(                                                   \
393       TRACE_EVENT_PHASE_END, category_group, ::perfetto::DynamicString{name}, \
394       TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},            \
395       ::perfetto::internal::PossiblyNull(arg1_val),                           \
396       ::perfetto::DynamicString{arg2_name},                                   \
397       ::perfetto::internal::PossiblyNull(arg2_val))
398 
399 // Mark events.
400 #define TRACE_EVENT_MARK_WITH_TIMESTAMP0(category_group, name, timestamp)  \
401   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(TRACE_EVENT_PHASE_MARK,          \
402                                           category_group, name, timestamp, \
403                                           TRACE_EVENT_FLAG_NONE)
404 
405 #define TRACE_EVENT_MARK_WITH_TIMESTAMP1(category_group, name, timestamp, \
406                                          arg1_name, arg1_val)             \
407   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                \
408       TRACE_EVENT_PHASE_MARK, category_group, name, timestamp,            \
409       TRACE_EVENT_FLAG_NONE, arg1_name,                                   \
410       ::perfetto::internal::PossiblyNull(arg1_val))
411 
412 #define TRACE_EVENT_MARK_WITH_TIMESTAMP2(                                      \
413     category_group, name, timestamp, arg1_name, arg1_val, arg2_name, arg2_val) \
414   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                     \
415       TRACE_EVENT_PHASE_MARK, category_group, name, timestamp,                 \
416       TRACE_EVENT_FLAG_NONE, arg1_name,                                        \
417       ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,                 \
418       ::perfetto::internal::PossiblyNull(arg2_val))
419 
420 #define TRACE_EVENT_COPY_MARK(category_group, name)                \
421   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_MARK, category_group, \
422                            ::perfetto::DynamicString{name},        \
423                            TRACE_EVENT_FLAG_NONE)
424 
425 #define TRACE_EVENT_COPY_MARK1(category_group, name, arg1_name, arg1_val)      \
426   INTERNAL_TRACE_EVENT_ADD(                                                    \
427       TRACE_EVENT_PHASE_MARK, category_group, ::perfetto::DynamicString{name}, \
428       TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},             \
429       ::perfetto::internal::PossiblyNull(arg1_val))
430 
431 #define TRACE_EVENT_COPY_MARK_WITH_TIMESTAMP(category_group, name, timestamp)  \
432   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                     \
433       TRACE_EVENT_PHASE_MARK, category_group, ::perfetto::DynamicString{name}, \
434       timestamp, TRACE_EVENT_FLAG_NONE)
435 
436 // End events with explicit thread and timestamp.
437 #define TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0(category_group, name, id, \
438                                                    thread_id, timestamp)     \
439   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                        \
440       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id,      \
441       timestamp, TRACE_EVENT_FLAG_NONE)
442 #define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0(         \
443     category_group, name, id, thread_id, timestamp)              \
444   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(            \
445       TRACE_EVENT_PHASE_ASYNC_END, category_group,               \
446       ::perfetto::DynamicString{name}, id, thread_id, timestamp, \
447       TRACE_EVENT_FLAG_NONE)
448 #define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP1(                 \
449     category_group, name, id, thread_id, timestamp, arg1_name, arg1_val) \
450   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                    \
451       TRACE_EVENT_PHASE_ASYNC_END, category_group,                       \
452       ::perfetto::DynamicString{name}, id, thread_id, timestamp,         \
453       TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},       \
454       ::perfetto::internal::PossiblyNull(arg1_val))
455 #define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP2(                 \
456     category_group, name, id, thread_id, timestamp, arg1_name, arg1_val, \
457     arg2_name, arg2_val)                                                 \
458   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                    \
459       TRACE_EVENT_PHASE_ASYNC_END, category_group,                       \
460       ::perfetto::DynamicString{name}, id, thread_id, timestamp,         \
461       TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name},       \
462       ::perfetto::internal::PossiblyNull(arg1_val),                      \
463       ::perfetto::DynamicString{arg2_name},                              \
464       ::perfetto::internal::PossiblyNull(arg2_val))
465 
466 // Counters.
467 #define TRACE_COUNTER1(category_group, name, value)                         \
468   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
469                            TRACE_EVENT_FLAG_NONE, "value",                  \
470                            static_cast<int>(value))
471 #define TRACE_COUNTER_WITH_FLAG1(category_group, name, flag, value)         \
472   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
473                            flag, "value", static_cast<int>(value))
474 #define TRACE_COPY_COUNTER1(category_group, name, value)              \
475   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, \
476                            ::perfetto::DynamicString{name},           \
477                            TRACE_EVENT_FLAG_NONE, "value",            \
478                            static_cast<int>(value))
479 #define TRACE_COUNTER2(category_group, name, value1_name, value1_val,       \
480                        value2_name, value2_val)                             \
481   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
482                            TRACE_EVENT_FLAG_NONE, value1_name,              \
483                            static_cast<int>(value1_val), value2_name,       \
484                            static_cast<int>(value2_val))
485 #define TRACE_COPY_COUNTER2(category_group, name, value1_name, value1_val, \
486                             value2_name, value2_val)                       \
487   INTERNAL_TRACE_EVENT_ADD(                                                \
488       TRACE_EVENT_PHASE_COUNTER, category_group,                           \
489       ::perfetto::DynamicString{name}, TRACE_EVENT_FLAG_NONE, value1_name, \
490       static_cast<int>(value1_val), value2_name, static_cast<int>(value2_val))
491 
492 // Counters with explicit timestamps.
493 #define TRACE_COUNTER_WITH_TIMESTAMP1(category_group, name, timestamp, value) \
494   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                    \
495       TRACE_EVENT_PHASE_COUNTER, category_group, name, timestamp,             \
496       TRACE_EVENT_FLAG_NONE, "value", static_cast<int>(value))
497 
498 #define TRACE_COUNTER_WITH_TIMESTAMP2(category_group, name, timestamp,      \
499                                       value1_name, value1_val, value2_name, \
500                                       value2_val)                           \
501   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                  \
502       TRACE_EVENT_PHASE_COUNTER, category_group, name, timestamp,           \
503       TRACE_EVENT_FLAG_NONE, value1_name, static_cast<int>(value1_val),     \
504       value2_name, static_cast<int>(value2_val))
505 
506 // Counters with ids.
507 #define TRACE_COUNTER_ID1(category_group, name, id, value)                    \
508   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
509                                    name, id, TRACE_EVENT_FLAG_NONE, "value",  \
510                                    static_cast<int>(value))
511 #define TRACE_COPY_COUNTER_ID1(category_group, name, id, value)               \
512   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
513                                    ::perfetto::DynamicString{name}, id,       \
514                                    TRACE_EVENT_FLAG_NONE, "value",            \
515                                    static_cast<int>(value))
516 #define TRACE_COUNTER_ID2(category_group, name, id, value1_name, value1_val,  \
517                           value2_name, value2_val)                            \
518   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
519                                    name, id, TRACE_EVENT_FLAG_NONE,           \
520                                    value1_name, static_cast<int>(value1_val), \
521                                    value2_name, static_cast<int>(value2_val))
522 #define TRACE_COPY_COUNTER_ID2(category_group, name, id, value1_name,          \
523                                value1_val, value2_name, value2_val)            \
524   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                            \
525       TRACE_EVENT_PHASE_COUNTER, category_group,                               \
526       ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE, value1_name, \
527       static_cast<int>(value1_val), value2_name, static_cast<int>(value2_val))
528 
529 // Sampling profiler events.
530 #define TRACE_EVENT_SAMPLE_WITH_ID1(category_group, name, id, arg1_name,       \
531                                     arg1_val)                                  \
532   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_SAMPLE, category_group,   \
533                                    name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \
534                                    arg1_val)
535 
536 // Legacy async events.
537 #define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id)        \
538   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
539                                    category_group, name, id,      \
540                                    TRACE_EVENT_FLAG_NONE)
541 #define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
542                                  arg1_val)                            \
543   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                   \
544       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,        \
545       TRACE_EVENT_FLAG_NONE, arg1_name,                               \
546       ::perfetto::internal::PossiblyNull(arg1_val))
547 #define TRACE_EVENT_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
548                                  arg1_val, arg2_name, arg2_val)       \
549   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                   \
550       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,        \
551       TRACE_EVENT_FLAG_NONE, arg1_name,                               \
552       ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,        \
553       ::perfetto::internal::PossiblyNull(arg2_val))
554 #define TRACE_EVENT_COPY_ASYNC_BEGIN0(category_group, name, id) \
555   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                             \
556       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,            \
557       ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE)
558 #define TRACE_EVENT_COPY_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
559                                       arg1_val)                            \
560   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                        \
561       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                       \
562       ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,          \
563       ::perfetto::DynamicString{arg1_name},                                \
564       ::perfetto::internal::PossiblyNull(arg1_val))
565 #define TRACE_EVENT_COPY_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
566                                       arg1_val, arg2_name, arg2_val)       \
567   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                        \
568       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                       \
569       ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,          \
570       ::perfetto::DynamicString{arg1_name},                                \
571       ::perfetto::internal::PossiblyNull(arg1_val),                        \
572       ::perfetto::DynamicString{arg2_name},                                \
573       ::perfetto::internal::PossiblyNull(arg2_val))
574 #define TRACE_EVENT_ASYNC_BEGIN_WITH_FLAGS0(category_group, name, id, flags) \
575   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN,            \
576                                    category_group, name, id, flags)
577 
578 // Legacy async events with explicit timestamps.
579 #define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, id, \
580                                                 timestamp)                \
581   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                     \
582       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,            \
583       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
584 #define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(                           \
585     category_group, name, id, timestamp, arg1_name, arg1_val)              \
586   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
587       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,             \
588       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
589       arg1_name, ::perfetto::internal::PossiblyNull(arg1_val))
590 #define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0(     \
591     category_group, name, id, timestamp, flags)                         \
592   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                   \
593       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
594       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
595 #define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(category_group, name, \
596                                                        id, timestamp)        \
597   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                        \
598       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,        \
599       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
600 #define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP2(category_group, name, id,      \
601                                                 timestamp, arg1_name,          \
602                                                 arg1_val, arg2_name, arg2_val) \
603   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
604       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,                 \
605       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,     \
606       arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,      \
607       ::perfetto::internal::PossiblyNull(arg2_val))
608 #define TRACE_EVENT_COPY_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, id, \
609                                                      timestamp)                \
610   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
611       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group,                           \
612       ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID,  \
613       timestamp, TRACE_EVENT_FLAG_NONE)
614 #define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0(     \
615     category_group, name, id, timestamp, flags)                \
616   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(          \
617       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
618       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
619 
620 // Legacy async step into events.
621 #define TRACE_EVENT_ASYNC_STEP_INTO0(category_group, name, id, step)  \
622   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP_INTO, \
623                                    category_group, name, id,          \
624                                    TRACE_EVENT_FLAG_NONE, "step", step)
625 #define TRACE_EVENT_ASYNC_STEP_INTO1(category_group, name, id, step, \
626                                      arg1_name, arg1_val)            \
627   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                  \
628       TRACE_EVENT_PHASE_ASYNC_STEP_INTO, category_group, name, id,   \
629       TRACE_EVENT_FLAG_NONE, "step", step, arg1_name,                \
630       ::perfetto::internal::PossiblyNull(arg1_val))
631 
632 // Legacy async step into events with timestamps.
633 #define TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(category_group, name, id, \
634                                                     step, timestamp)          \
635   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
636       TRACE_EVENT_PHASE_ASYNC_STEP_INTO, category_group, name, id,            \
637       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,    \
638       "step", step)
639 
640 // Legacy async step past events.
641 #define TRACE_EVENT_ASYNC_STEP_PAST0(category_group, name, id, step)  \
642   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP_PAST, \
643                                    category_group, name, id,          \
644                                    TRACE_EVENT_FLAG_NONE, "step", step)
645 #define TRACE_EVENT_ASYNC_STEP_PAST1(category_group, name, id, step, \
646                                      arg1_name, arg1_val)            \
647   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                  \
648       TRACE_EVENT_PHASE_ASYNC_STEP_PAST, category_group, name, id,   \
649       TRACE_EVENT_FLAG_NONE, "step", step, arg1_name,                \
650       ::perfetto::internal::PossiblyNull(arg1_val))
651 
652 // Legacy async end events.
653 #define TRACE_EVENT_ASYNC_END0(category_group, name, id)        \
654   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
655                                    category_group, name, id,    \
656                                    TRACE_EVENT_FLAG_NONE)
657 #define TRACE_EVENT_ASYNC_END1(category_group, name, id, arg1_name, arg1_val) \
658   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                           \
659       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
660       TRACE_EVENT_FLAG_NONE, arg1_name,                                       \
661       ::perfetto::internal::PossiblyNull(arg1_val))
662 #define TRACE_EVENT_ASYNC_END2(category_group, name, id, arg1_name, arg1_val, \
663                                arg2_name, arg2_val)                           \
664   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                           \
665       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
666       TRACE_EVENT_FLAG_NONE, arg1_name,                                       \
667       ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,                \
668       ::perfetto::internal::PossiblyNull(arg2_val))
669 #define TRACE_EVENT_COPY_ASYNC_END0(category_group, name, id) \
670   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                           \
671       TRACE_EVENT_PHASE_ASYNC_END, category_group,            \
672       ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE)
673 #define TRACE_EVENT_COPY_ASYNC_END1(category_group, name, id, arg1_name, \
674                                     arg1_val)                            \
675   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                      \
676       TRACE_EVENT_PHASE_ASYNC_END, category_group,                       \
677       ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,        \
678       ::perfetto::DynamicString{arg1_name},                              \
679       ::perfetto::internal::PossiblyNull(arg1_val))
680 #define TRACE_EVENT_COPY_ASYNC_END2(category_group, name, id, arg1_name, \
681                                     arg1_val, arg2_name, arg2_val)       \
682   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                      \
683       TRACE_EVENT_PHASE_ASYNC_END, category_group,                       \
684       ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,        \
685       ::perfetto::DynamicString{arg1_name},                              \
686       ::perfetto::internal::PossiblyNull(arg1_val),                      \
687       ::perfetto::DynamicString{arg2_name},                              \
688       ::perfetto::internal::PossiblyNull(arg2_val))
689 #define TRACE_EVENT_ASYNC_END_WITH_FLAGS0(category_group, name, id, flags) \
690   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END,            \
691                                    category_group, name, id, flags)
692 
693 // Legacy async end events with explicit timestamps.
694 #define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(category_group, name, id, \
695                                               timestamp)                \
696   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                   \
697       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,            \
698       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
699 #define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP1(category_group, name, id,       \
700                                               timestamp, arg1_name, arg1_val) \
701   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
702       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
703       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,    \
704       arg1_name, ::perfetto::internal::PossiblyNull(arg1_val))
705 #define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP2(category_group, name, id,       \
706                                               timestamp, arg1_name, arg1_val, \
707                                               arg2_name, arg2_val)            \
708   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
709       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
710       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,    \
711       arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,     \
712       ::perfetto::internal::PossiblyNull(arg2_val))
713 #define TRACE_EVENT_COPY_ASYNC_END_WITH_TIMESTAMP0(category_group, name, id,  \
714                                                    timestamp)                 \
715   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
716       TRACE_EVENT_PHASE_ASYNC_END, category_group,                            \
717       ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID, \
718       timestamp, TRACE_EVENT_FLAG_NONE)
719 #define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0(category_group, name, \
720                                                         id, timestamp, flags) \
721   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
722       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
723       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
724 
725 // Async events.
726 #define TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(category_group, name, id)        \
727   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
728                                    category_group, name, id,               \
729                                    TRACE_EVENT_FLAG_NONE)
730 #define TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
731                                           arg1_val)                            \
732   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                            \
733       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,        \
734       TRACE_EVENT_FLAG_NONE, arg1_name,                                        \
735       ::perfetto::internal::PossiblyNull(arg1_val))
736 #define TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
737                                           arg1_val, arg2_name, arg2_val)       \
738   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                            \
739       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,        \
740       TRACE_EVENT_FLAG_NONE, arg1_name,                                        \
741       ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,                 \
742       ::perfetto::internal::PossiblyNull(arg2_val))
743 #define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_FLAGS0(category_group, name, id, \
744                                                      flags)                    \
745   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN,     \
746                                    category_group, name, id, flags)
747 #define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP1(                  \
748     category_group, name, id, timestamp, arg1_name, arg1_val)              \
749   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
750       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,    \
751       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
752       arg1_name, ::perfetto::internal::PossiblyNull(arg1_val))
753 
754 // Async end events.
755 #define TRACE_EVENT_NESTABLE_ASYNC_END0(category_group, name, id)        \
756   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
757                                    category_group, name, id,             \
758                                    TRACE_EVENT_FLAG_NONE)
759 #define TRACE_EVENT_NESTABLE_ASYNC_END1(category_group, name, id, arg1_name, \
760                                         arg1_val)                            \
761   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                          \
762       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,        \
763       TRACE_EVENT_FLAG_NONE, arg1_name,                                      \
764       ::perfetto::internal::PossiblyNull(arg1_val))
765 #define TRACE_EVENT_NESTABLE_ASYNC_END2(category_group, name, id, arg1_name, \
766                                         arg1_val, arg2_name, arg2_val)       \
767   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                          \
768       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,        \
769       TRACE_EVENT_FLAG_NONE, arg1_name,                                      \
770       ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,               \
771       ::perfetto::internal::PossiblyNull(arg2_val))
772 #define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_FLAGS0(category_group, name, id, \
773                                                    flags)                    \
774   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END,     \
775                                    category_group, name, id, flags)
776 
777 // Async instant events.
778 #define TRACE_EVENT_NESTABLE_ASYNC_INSTANT0(category_group, name, id)        \
779   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, \
780                                    category_group, name, id,                 \
781                                    TRACE_EVENT_FLAG_NONE)
782 #define TRACE_EVENT_NESTABLE_ASYNC_INSTANT1(category_group, name, id,     \
783                                             arg1_name, arg1_val)          \
784   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                       \
785       TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, category_group, name, id, \
786       TRACE_EVENT_FLAG_NONE, arg1_name,                                   \
787       ::perfetto::internal::PossiblyNull(arg1_val))
788 #define TRACE_EVENT_NESTABLE_ASYNC_INSTANT2(                              \
789     category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val)   \
790   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                       \
791       TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, category_group, name, id, \
792       TRACE_EVENT_FLAG_NONE, arg1_name,                                   \
793       ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,            \
794       ::perfetto::internal::PossiblyNull(arg2_val))
795 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TTS2(                \
796     category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
797   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                     \
798       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,           \
799       ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_ASYNC_TTS,  \
800       ::perfetto::DynamicString{arg1_name},                             \
801       ::perfetto::internal::PossiblyNull(arg1_val),                     \
802       ::perfetto::DynamicString{arg2_name},                             \
803       ::perfetto::internal::PossiblyNull(arg2_val))
804 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TTS2(                  \
805     category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
806   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                     \
807       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group,             \
808       ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_ASYNC_TTS,  \
809       ::perfetto::DynamicString{arg1_name},                             \
810       ::perfetto::internal::PossiblyNull(arg1_val),                     \
811       ::perfetto::DynamicString{arg2_name},                             \
812       ::perfetto::internal::PossiblyNull(arg2_val))
813 
814 // Async events with explicit timestamps.
815 #define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, \
816                                                          id, timestamp)        \
817   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
818       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,        \
819       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
820 #define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(category_group, name, \
821                                                        id, timestamp)        \
822   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                        \
823       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,        \
824       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
825 #define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP1(                    \
826     category_group, name, id, timestamp, arg1_name, arg1_val)              \
827   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
828       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,      \
829       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
830       arg1_name, ::perfetto::internal::PossiblyNull(arg1_val))
831 #define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP2(                    \
832     category_group, name, id, timestamp, arg1_name, arg1_val, arg2_name,   \
833     arg2_val)                                                              \
834   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
835       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,      \
836       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
837       arg1_name, ::perfetto::internal::PossiblyNull(arg1_val), arg2_name,  \
838       ::perfetto::internal::PossiblyNull(arg2_val))
839 #define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0(     \
840     category_group, name, id, timestamp, flags)                       \
841   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                 \
842       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
843       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
844 #define TRACE_EVENT_NESTABLE_ASYNC_INSTANT_WITH_TIMESTAMP0(               \
845     category_group, name, id, timestamp)                                  \
846   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                     \
847       TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, category_group, name, id, \
848       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
849 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN0(category_group, name, id) \
850   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                      \
851       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,            \
852       ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE)
853 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN1(category_group, name, id, \
854                                                arg1_name, arg1_val)      \
855   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                      \
856       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,            \
857       ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,        \
858       ::perfetto::DynamicString{arg1_name},                              \
859       ::perfetto::internal::PossiblyNull(arg1_val))
860 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN2(                         \
861     category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val) \
862   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                     \
863       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,           \
864       ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE,       \
865       ::perfetto::DynamicString{arg1_name},                             \
866       ::perfetto::internal::PossiblyNull(arg1_val),                     \
867       ::perfetto::DynamicString{arg2_name},                             \
868       ::perfetto::internal::PossiblyNull(arg2_val))
869 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_END0(category_group, name, id) \
870   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                    \
871       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group,            \
872       ::perfetto::DynamicString{name}, id, TRACE_EVENT_FLAG_NONE)
873 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(                \
874     category_group, name, id, timestamp)                                      \
875   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
876       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,                 \
877       ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID, \
878       timestamp, TRACE_EVENT_FLAG_NONE)
879 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP1(                \
880     category_group, name, id, timestamp, arg1_name, arg1_val)                 \
881   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
882       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group,                 \
883       ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID, \
884       timestamp, TRACE_EVENT_FLAG_NONE, ::perfetto::DynamicString{arg1_name}, \
885       ::perfetto::internal::PossiblyNull(arg1_val))
886 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(                  \
887     category_group, name, id, timestamp)                                      \
888   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
889       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group,                   \
890       ::perfetto::DynamicString{name}, id, TRACE_EVENT_API_CURRENT_THREAD_ID, \
891       timestamp, TRACE_EVENT_FLAG_NONE)
892 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TIMESTAMP2(               \
893     category_group, name, id, timestamp, arg1_name, arg1_val, arg2_name,   \
894     arg2_val)                                                              \
895   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
896       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,      \
897       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
898       ::perfetto::DynamicString{arg1_name},                                \
899       ::perfetto::internal::PossiblyNull(arg1_val),                        \
900       ::perfetto::DynamicString{arg2_name},                                \
901       ::perfetto::internal::PossiblyNull(arg2_val))
902 
903 // Metadata events.
904 #define TRACE_EVENT_METADATA1(category_group, name, arg1_name, arg1_val) \
905   INTERNAL_TRACE_EVENT_METADATA_ADD(                                     \
906       category_group, name, arg1_name,                                   \
907       ::perfetto::internal::PossiblyNull(arg1_val))
908 
909 // Clock sync events.
910 #define TRACE_EVENT_CLOCK_SYNC_RECEIVER(sync_id)                           \
911   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_CLOCK_SYNC, "__metadata",     \
912                            "clock_sync", TRACE_EVENT_FLAG_NONE, "sync_id", \
913                            sync_id)
914 #define TRACE_EVENT_CLOCK_SYNC_ISSUER(sync_id, issue_ts, issue_end_ts)        \
915   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                    \
916       TRACE_EVENT_PHASE_CLOCK_SYNC, "__metadata", "clock_sync", issue_end_ts, \
917       TRACE_EVENT_FLAG_NONE, "sync_id", sync_id, "issue_ts", issue_ts)
918 
919 // Object events.
920 #define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) \
921   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_CREATE_OBJECT,  \
922                                    category_group, name, id,         \
923                                    TRACE_EVENT_FLAG_NONE)
924 
925 #define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, \
926                                             snapshot)                 \
927   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                   \
928       TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, category_group, name, id,    \
929       TRACE_EVENT_FLAG_NONE, "snapshot", snapshot)
930 
931 #define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID_AND_TIMESTAMP(                 \
932     category_group, name, id, timestamp, snapshot)                         \
933   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
934       TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, category_group, name, id,         \
935       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
936       "snapshot", snapshot)
937 
938 #define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) \
939   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_DELETE_OBJECT,  \
940                                    category_group, name, id,         \
941                                    TRACE_EVENT_FLAG_NONE)
942 
943 // TODO(skyostil): Implement binary-efficient trace events.
944 #define TRACE_EVENT_BINARY_EFFICIENT0 TRACE_EVENT0
945 #define TRACE_EVENT_BINARY_EFFICIENT1 TRACE_EVENT1
946 #define TRACE_EVENT_BINARY_EFFICIENT2 TRACE_EVENT2
947 
948 // Macro to efficiently determine if a given category group is enabled.
949 #define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category, ret) \
950   do {                                                    \
951     *ret = TRACE_EVENT_CATEGORY_ENABLED(category);        \
952   } while (0)
953 
954 // Macro to efficiently determine, through polling, if a new trace has begun.
955 #define TRACE_EVENT_IS_NEW_TRACE(ret)                                \
956   do {                                                               \
957     static int PERFETTO_UID(prev) = -1;                              \
958     int PERFETTO_UID(curr) =                                         \
959         ::perfetto::internal::TrackEventInternal::GetSessionCount(); \
960     if (PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsEnabled() &&   \
961         (PERFETTO_UID(prev) != PERFETTO_UID(curr))) {                \
962       *(ret) = true;                                                 \
963       PERFETTO_UID(prev) = PERFETTO_UID(curr);                       \
964     } else {                                                         \
965       *(ret) = false;                                                \
966     }                                                                \
967   } while (0)
968 
969 // ----------------------------------------------------------------------------
970 // Legacy tracing API (adapted from trace_event.h).
971 // ----------------------------------------------------------------------------
972 
973 // We can implement the following subset of the legacy tracing API without
974 // involvement from the embedder. APIs such as TRACE_EVENT_API_ADD_TRACE_EVENT
975 // are still up to the embedder to define.
976 
977 #define TRACE_STR_COPY(str) \
978   ::perfetto::DynamicString { ::perfetto::internal::PossiblyNull(str) }
979 
980 #define TRACE_ID_WITH_SCOPE(scope, ...) \
981   ::perfetto::internal::LegacyTraceId::WithScope(scope, ##__VA_ARGS__)
982 
983 // Use this for ids that are unique across processes. This allows different
984 // processes to use the same id to refer to the same event.
985 #define TRACE_ID_GLOBAL(id) ::perfetto::internal::LegacyTraceId::GlobalId(id)
986 
987 // Use this for ids that are unique within a single process. This allows
988 // different processes to use the same id to refer to different events.
989 #define TRACE_ID_LOCAL(id) ::perfetto::internal::LegacyTraceId::LocalId(id)
990 
991 // Returns a pointer to a uint8_t which indicates whether tracing is enabled for
992 // the given category or not. A zero value means tracing is disabled and
993 // non-zero indicates at least one tracing session for this category is active.
994 // Note that callers should not make any assumptions at what each bit represents
995 // in the status byte. Does not support dynamic categories.
996 #define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category)              \
997   reinterpret_cast<const uint8_t*>(                                       \
998       [&] {                                                               \
999         static_assert(                                                    \
1000             !std::is_same<::perfetto::DynamicCategory,                    \
1001                           decltype(category)>::value,                     \
1002             "Enabled flag pointers are not supported for dynamic trace "  \
1003             "categories.");                                               \
1004       },                                                                  \
1005       PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry         \
1006           .GetCategoryState(                                              \
1007               PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
1008                   .Find(category, /*is_dynamic=*/false)))
1009 
1010 // Given a pointer returned by TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED,
1011 // yields a pointer to the name of the corresponding category group.
1012 #define TRACE_EVENT_API_GET_CATEGORY_GROUP_NAME(category_enabled_ptr)     \
1013   PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry             \
1014       .GetCategory(                                                       \
1015           category_enabled_ptr -                                          \
1016           reinterpret_cast<const uint8_t*>(                               \
1017               PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
1018                   .GetCategoryState(0u)))                                 \
1019       ->name
1020 
1021 #endif  // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
1022 
1023 #endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_LEGACY_H_
1024