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 // Constants.
41 // ----------------------------------------------------------------------------
42 
43 namespace perfetto {
44 namespace legacy {
45 
46 enum TraceEventFlag {
47   kTraceEventFlagNone = 0,
48   kTraceEventFlagCopy = 1u << 0,
49   kTraceEventFlagHasId = 1u << 1,
50   kTraceEventFlagScopeOffset = 1u << 2,
51   kTraceEventFlagScopeExtra = 1u << 3,
52   kTraceEventFlagExplicitTimestamp = 1u << 4,
53   kTraceEventFlagAsyncTTS = 1u << 5,
54   kTraceEventFlagBindToEnclosing = 1u << 6,
55   kTraceEventFlagFlowIn = 1u << 7,
56   kTraceEventFlagFlowOut = 1u << 8,
57   kTraceEventFlagHasContextId = 1u << 9,
58   kTraceEventFlagHasProcessId = 1u << 10,
59   kTraceEventFlagHasLocalId = 1u << 11,
60   kTraceEventFlagHasGlobalId = 1u << 12,
61   // TODO(eseckler): Remove once we have native support for typed proto events
62   // in TRACE_EVENT macros.
63   kTraceEventFlagTypedProtoArgs = 1u << 15,
64   kTraceEventFlagJavaStringLiterals = 1u << 16,
65 };
66 
67 enum PerfettoLegacyCurrentThreadId { kCurrentThreadId };
68 
69 }  // namespace legacy
70 }  // namespace perfetto
71 
72 #if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
73 // The following constants are defined in the global namespace, since they were
74 // originally implemented as macros.
75 
76 // Event phases.
77 static constexpr char TRACE_EVENT_PHASE_BEGIN = 'B';
78 static constexpr char TRACE_EVENT_PHASE_END = 'E';
79 static constexpr char TRACE_EVENT_PHASE_COMPLETE = 'X';
80 static constexpr char TRACE_EVENT_PHASE_INSTANT = 'I';
81 static constexpr char TRACE_EVENT_PHASE_ASYNC_BEGIN = 'S';
82 static constexpr char TRACE_EVENT_PHASE_ASYNC_STEP_INTO = 'T';
83 static constexpr char TRACE_EVENT_PHASE_ASYNC_STEP_PAST = 'p';
84 static constexpr char TRACE_EVENT_PHASE_ASYNC_END = 'F';
85 static constexpr char TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN = 'b';
86 static constexpr char TRACE_EVENT_PHASE_NESTABLE_ASYNC_END = 'e';
87 static constexpr char TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT = 'n';
88 static constexpr char TRACE_EVENT_PHASE_FLOW_BEGIN = 's';
89 static constexpr char TRACE_EVENT_PHASE_FLOW_STEP = 't';
90 static constexpr char TRACE_EVENT_PHASE_FLOW_END = 'f';
91 static constexpr char TRACE_EVENT_PHASE_METADATA = 'M';
92 static constexpr char TRACE_EVENT_PHASE_COUNTER = 'C';
93 static constexpr char TRACE_EVENT_PHASE_SAMPLE = 'P';
94 static constexpr char TRACE_EVENT_PHASE_CREATE_OBJECT = 'N';
95 static constexpr char TRACE_EVENT_PHASE_SNAPSHOT_OBJECT = 'O';
96 static constexpr char TRACE_EVENT_PHASE_DELETE_OBJECT = 'D';
97 static constexpr char TRACE_EVENT_PHASE_MEMORY_DUMP = 'v';
98 static constexpr char TRACE_EVENT_PHASE_MARK = 'R';
99 static constexpr char TRACE_EVENT_PHASE_CLOCK_SYNC = 'c';
100 static constexpr char TRACE_EVENT_PHASE_ENTER_CONTEXT = '(';
101 static constexpr char TRACE_EVENT_PHASE_LEAVE_CONTEXT = ')';
102 
103 // Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
104 static constexpr uint32_t TRACE_EVENT_FLAG_NONE =
105     perfetto::legacy::kTraceEventFlagNone;
106 static constexpr uint32_t TRACE_EVENT_FLAG_COPY =
107     perfetto::legacy::kTraceEventFlagCopy;
108 static constexpr uint32_t TRACE_EVENT_FLAG_HAS_ID =
109     perfetto::legacy::kTraceEventFlagHasId;
110 static constexpr uint32_t TRACE_EVENT_FLAG_SCOPE_OFFSET =
111     perfetto::legacy::kTraceEventFlagScopeOffset;
112 static constexpr uint32_t TRACE_EVENT_FLAG_SCOPE_EXTRA =
113     perfetto::legacy::kTraceEventFlagScopeExtra;
114 static constexpr uint32_t TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP =
115     perfetto::legacy::kTraceEventFlagExplicitTimestamp;
116 static constexpr uint32_t TRACE_EVENT_FLAG_ASYNC_TTS =
117     perfetto::legacy::kTraceEventFlagAsyncTTS;
118 static constexpr uint32_t TRACE_EVENT_FLAG_BIND_TO_ENCLOSING =
119     perfetto::legacy::kTraceEventFlagBindToEnclosing;
120 static constexpr uint32_t TRACE_EVENT_FLAG_FLOW_IN =
121     perfetto::legacy::kTraceEventFlagFlowIn;
122 static constexpr uint32_t TRACE_EVENT_FLAG_FLOW_OUT =
123     perfetto::legacy::kTraceEventFlagFlowOut;
124 static constexpr uint32_t TRACE_EVENT_FLAG_HAS_CONTEXT_ID =
125     perfetto::legacy::kTraceEventFlagHasContextId;
126 static constexpr uint32_t TRACE_EVENT_FLAG_HAS_PROCESS_ID =
127     perfetto::legacy::kTraceEventFlagHasProcessId;
128 static constexpr uint32_t TRACE_EVENT_FLAG_HAS_LOCAL_ID =
129     perfetto::legacy::kTraceEventFlagHasLocalId;
130 static constexpr uint32_t TRACE_EVENT_FLAG_HAS_GLOBAL_ID =
131     perfetto::legacy::kTraceEventFlagHasGlobalId;
132 static constexpr uint32_t TRACE_EVENT_FLAG_TYPED_PROTO_ARGS =
133     perfetto::legacy::kTraceEventFlagTypedProtoArgs;
134 static constexpr uint32_t TRACE_EVENT_FLAG_JAVA_STRING_LITERALS =
135     perfetto::legacy::kTraceEventFlagJavaStringLiterals;
136 
137 static constexpr uint32_t TRACE_EVENT_FLAG_SCOPE_MASK =
138     TRACE_EVENT_FLAG_SCOPE_OFFSET | TRACE_EVENT_FLAG_SCOPE_EXTRA;
139 
140 // Type values for identifying types in the TraceValue union.
141 static constexpr uint8_t TRACE_VALUE_TYPE_BOOL = 1;
142 static constexpr uint8_t TRACE_VALUE_TYPE_UINT = 2;
143 static constexpr uint8_t TRACE_VALUE_TYPE_INT = 3;
144 static constexpr uint8_t TRACE_VALUE_TYPE_DOUBLE = 4;
145 static constexpr uint8_t TRACE_VALUE_TYPE_POINTER = 5;
146 static constexpr uint8_t TRACE_VALUE_TYPE_STRING = 6;
147 static constexpr uint8_t TRACE_VALUE_TYPE_COPY_STRING = 7;
148 static constexpr uint8_t TRACE_VALUE_TYPE_CONVERTABLE = 8;
149 static constexpr uint8_t TRACE_VALUE_TYPE_PROTO = 9;
150 
151 // Enum reflecting the scope of an INSTANT event. Must fit within
152 // TRACE_EVENT_FLAG_SCOPE_MASK.
153 static constexpr uint8_t TRACE_EVENT_SCOPE_GLOBAL = 0u << 2;
154 static constexpr uint8_t TRACE_EVENT_SCOPE_PROCESS = 1u << 2;
155 static constexpr uint8_t TRACE_EVENT_SCOPE_THREAD = 2u << 2;
156 
157 static constexpr char TRACE_EVENT_SCOPE_NAME_GLOBAL = 'g';
158 static constexpr char TRACE_EVENT_SCOPE_NAME_PROCESS = 'p';
159 static constexpr char TRACE_EVENT_SCOPE_NAME_THREAD = 't';
160 
161 static constexpr auto TRACE_EVENT_API_CURRENT_THREAD_ID =
162     perfetto::legacy::kCurrentThreadId;
163 
164 #endif  // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
165 
166 // ----------------------------------------------------------------------------
167 // Internal legacy trace point implementation.
168 // ----------------------------------------------------------------------------
169 
170 namespace perfetto {
171 namespace legacy {
172 
173 // The following user-provided adaptors are used to serialize user-defined
174 // thread id and time types into track events. For full compatibility, the user
175 // should also define the following macros appropriately:
176 //
177 //   #define TRACE_TIME_TICKS_NOW() ...
178 //   #define TRACE_TIME_NOW() ...
179 
180 // User-provided function to convert an abstract thread id into a thread track.
181 template <typename T>
182 ThreadTrack ConvertThreadId(const T&);
183 
184 // Built-in implementation for events referring to the current thread.
185 template <>
186 ThreadTrack PERFETTO_EXPORT
187 ConvertThreadId(const PerfettoLegacyCurrentThreadId&);
188 
189 }  // namespace legacy
190 
191 namespace internal {
192 
193 // LegacyTraceId encapsulates an ID that can either be an integer or pointer.
194 class PERFETTO_EXPORT LegacyTraceId {
195  public:
196   // Can be combined with WithScope.
197   class LocalId {
198    public:
LocalId(const void * raw_id)199     explicit LocalId(const void* raw_id)
200         : raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {}
LocalId(uint64_t raw_id)201     explicit LocalId(uint64_t raw_id) : raw_id_(raw_id) {}
raw_id()202     uint64_t raw_id() const { return raw_id_; }
203 
204    private:
205     uint64_t raw_id_;
206   };
207 
208   // Can be combined with WithScope.
209   class GlobalId {
210    public:
GlobalId(uint64_t raw_id)211     explicit GlobalId(uint64_t raw_id) : raw_id_(raw_id) {}
raw_id()212     uint64_t raw_id() const { return raw_id_; }
213 
214    private:
215     uint64_t raw_id_;
216   };
217 
218   class WithScope {
219    public:
WithScope(const char * scope,uint64_t raw_id)220     WithScope(const char* scope, uint64_t raw_id)
221         : scope_(scope), raw_id_(raw_id) {}
WithScope(const char * scope,LocalId local_id)222     WithScope(const char* scope, LocalId local_id)
223         : scope_(scope), raw_id_(local_id.raw_id()) {
224       id_flags_ = legacy::kTraceEventFlagHasLocalId;
225     }
WithScope(const char * scope,GlobalId global_id)226     WithScope(const char* scope, GlobalId global_id)
227         : scope_(scope), raw_id_(global_id.raw_id()) {
228       id_flags_ = legacy::kTraceEventFlagHasGlobalId;
229     }
WithScope(const char * scope,uint64_t prefix,uint64_t raw_id)230     WithScope(const char* scope, uint64_t prefix, uint64_t raw_id)
231         : scope_(scope), has_prefix_(true), prefix_(prefix), raw_id_(raw_id) {}
WithScope(const char * scope,uint64_t prefix,GlobalId global_id)232     WithScope(const char* scope, uint64_t prefix, GlobalId global_id)
233         : scope_(scope),
234           has_prefix_(true),
235           prefix_(prefix),
236           raw_id_(global_id.raw_id()) {
237       id_flags_ = legacy::kTraceEventFlagHasGlobalId;
238     }
raw_id()239     uint64_t raw_id() const { return raw_id_; }
scope()240     const char* scope() const { return scope_; }
has_prefix()241     bool has_prefix() const { return has_prefix_; }
prefix()242     uint64_t prefix() const { return prefix_; }
id_flags()243     uint32_t id_flags() const { return id_flags_; }
244 
245    private:
246     const char* scope_ = nullptr;
247     bool has_prefix_ = false;
248     uint64_t prefix_;
249     uint64_t raw_id_;
250     uint32_t id_flags_ = legacy::kTraceEventFlagHasId;
251   };
252 
LegacyTraceId(const void * raw_id)253   explicit LegacyTraceId(const void* raw_id)
254       : raw_id_(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(raw_id))) {
255     id_flags_ = legacy::kTraceEventFlagHasLocalId;
256   }
LegacyTraceId(uint64_t raw_id)257   explicit LegacyTraceId(uint64_t raw_id) : raw_id_(raw_id) {}
LegacyTraceId(uint32_t raw_id)258   explicit LegacyTraceId(uint32_t raw_id) : raw_id_(raw_id) {}
LegacyTraceId(uint16_t raw_id)259   explicit LegacyTraceId(uint16_t raw_id) : raw_id_(raw_id) {}
LegacyTraceId(uint8_t raw_id)260   explicit LegacyTraceId(uint8_t raw_id) : raw_id_(raw_id) {}
LegacyTraceId(int64_t raw_id)261   explicit LegacyTraceId(int64_t raw_id)
262       : raw_id_(static_cast<uint64_t>(raw_id)) {}
LegacyTraceId(int32_t raw_id)263   explicit LegacyTraceId(int32_t raw_id)
264       : raw_id_(static_cast<uint64_t>(raw_id)) {}
LegacyTraceId(int16_t raw_id)265   explicit LegacyTraceId(int16_t raw_id)
266       : raw_id_(static_cast<uint64_t>(raw_id)) {}
LegacyTraceId(int8_t raw_id)267   explicit LegacyTraceId(int8_t raw_id)
268       : raw_id_(static_cast<uint64_t>(raw_id)) {}
LegacyTraceId(LocalId raw_id)269   explicit LegacyTraceId(LocalId raw_id) : raw_id_(raw_id.raw_id()) {
270     id_flags_ = legacy::kTraceEventFlagHasLocalId;
271   }
LegacyTraceId(GlobalId raw_id)272   explicit LegacyTraceId(GlobalId raw_id) : raw_id_(raw_id.raw_id()) {
273     id_flags_ = legacy::kTraceEventFlagHasGlobalId;
274   }
LegacyTraceId(WithScope scoped_id)275   explicit LegacyTraceId(WithScope scoped_id)
276       : scope_(scoped_id.scope()),
277         has_prefix_(scoped_id.has_prefix()),
278         prefix_(scoped_id.prefix()),
279         raw_id_(scoped_id.raw_id()),
280         id_flags_(scoped_id.id_flags()) {}
281 
raw_id()282   uint64_t raw_id() const { return raw_id_; }
scope()283   const char* scope() const { return scope_; }
has_prefix()284   bool has_prefix() const { return has_prefix_; }
prefix()285   uint64_t prefix() const { return prefix_; }
id_flags()286   uint32_t id_flags() const { return id_flags_; }
287 
288   void Write(protos::pbzero::TrackEvent::LegacyEvent*,
289              uint32_t event_flags) const;
290 
291  private:
292   const char* scope_ = nullptr;
293   bool has_prefix_ = false;
294   uint64_t prefix_;
295   uint64_t raw_id_;
296   uint32_t id_flags_ = legacy::kTraceEventFlagHasId;
297 };
298 
299 }  // namespace internal
300 }  // namespace perfetto
301 
302 #if PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
303 
304 namespace perfetto {
305 namespace internal {
306 
307 class PERFETTO_EXPORT TrackEventLegacy {
308  public:
PhaseToType(char phase)309   static constexpr protos::pbzero::TrackEvent::Type PhaseToType(char phase) {
310     // clang-format off
311     return (phase == TRACE_EVENT_PHASE_BEGIN) ?
312                protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN :
313            (phase == TRACE_EVENT_PHASE_END) ?
314                protos::pbzero::TrackEvent::TYPE_SLICE_END :
315            (phase == TRACE_EVENT_PHASE_INSTANT) ?
316                protos::pbzero::TrackEvent::TYPE_INSTANT :
317            protos::pbzero::TrackEvent::TYPE_UNSPECIFIED;
318     // clang-format on
319   }
320 
321   // Reduce binary size overhead by outlining most of the code for writing a
322   // legacy trace event.
323   template <typename... Args>
WriteLegacyEvent(EventContext ctx,char phase,uint32_t flags,Args &&...args)324   static void WriteLegacyEvent(EventContext ctx,
325                                char phase,
326                                uint32_t flags,
327                                Args&&... args) PERFETTO_NO_INLINE {
328     AddDebugAnnotations(&ctx, std::forward<Args>(args)...);
329     if (NeedLegacyFlags(phase, flags)) {
330       auto legacy_event = ctx.event()->set_legacy_event();
331       SetLegacyFlags(legacy_event, phase, flags);
332     }
333   }
334 
335   template <typename ThreadIdType, typename... Args>
WriteLegacyEventWithIdAndTid(EventContext ctx,char phase,uint32_t flags,const LegacyTraceId & id,const ThreadIdType & thread_id,Args &&...args)336   static void WriteLegacyEventWithIdAndTid(EventContext ctx,
337                                            char phase,
338                                            uint32_t flags,
339                                            const LegacyTraceId& id,
340                                            const ThreadIdType& thread_id,
341                                            Args&&... args) PERFETTO_NO_INLINE {
342     //
343     // Overrides to consider:
344     //
345     // 1. If we have an id, we need to write {unscoped,local,global}_id and/or
346     //    bind_id.
347     // 2. If we have a thread id, we need to write track_uuid() or
348     //    {pid,tid}_override if the id represents another process.  The
349     //    conversion from |thread_id| happens in embedder code since the type is
350     //    embedder-specified.
351     // 3. If we have a timestamp, we need to write a different timestamp in the
352     //    trace packet itself and make sure TrackEvent won't write one
353     //    internally. This is already done at the call site.
354     //
355     flags |= id.id_flags();
356     AddDebugAnnotations(&ctx, std::forward<Args>(args)...);
357     if (NeedLegacyFlags(phase, flags)) {
358       auto legacy_event = ctx.event()->set_legacy_event();
359       SetLegacyFlags(legacy_event, phase, flags);
360       if (id.id_flags())
361         id.Write(legacy_event, flags);
362       if (flags & TRACE_EVENT_FLAG_HAS_PROCESS_ID) {
363         // The thread identifier actually represents a process id. Let's set an
364         // override for it.
365         int32_t pid_override =
366             static_cast<int32_t>(legacy::ConvertThreadId(thread_id).tid);
367         legacy_event->set_pid_override(pid_override);
368         legacy_event->set_tid_override(-1);
369       }
370     }
371   }
372 
373   // No arguments.
AddDebugAnnotations(EventContext *)374   static void AddDebugAnnotations(EventContext*) {}
375 
376   // One argument.
377   template <typename ArgType>
AddDebugAnnotations(EventContext * ctx,const char * arg_name,ArgType && arg_value)378   static void AddDebugAnnotations(EventContext* ctx,
379                                   const char* arg_name,
380                                   ArgType&& arg_value) {
381     TrackEventInternal::AddDebugAnnotation(ctx, arg_name, arg_value);
382   }
383 
384   // Two arguments.
385   template <typename ArgType, typename ArgType2>
AddDebugAnnotations(EventContext * ctx,const char * arg_name,ArgType && arg_value,const char * arg_name2,ArgType2 && arg_value2)386   static void AddDebugAnnotations(EventContext* ctx,
387                                   const char* arg_name,
388                                   ArgType&& arg_value,
389                                   const char* arg_name2,
390                                   ArgType2&& arg_value2) {
391     TrackEventInternal::AddDebugAnnotation(ctx, arg_name, arg_value);
392     TrackEventInternal::AddDebugAnnotation(ctx, arg_name2, arg_value2);
393   }
394 
395  private:
NeedLegacyFlags(char phase,uint32_t flags)396   static bool NeedLegacyFlags(char phase, uint32_t flags) {
397     if (PhaseToType(phase) == protos::pbzero::TrackEvent::TYPE_UNSPECIFIED)
398       return true;
399     // TODO(skyostil): Implement/deprecate:
400     // - TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP
401     // - TRACE_EVENT_FLAG_HAS_CONTEXT_ID
402     // - TRACE_EVENT_FLAG_TYPED_PROTO_ARGS
403     // - TRACE_EVENT_FLAG_JAVA_STRING_LITERALS
404     return flags &
405            (TRACE_EVENT_FLAG_HAS_ID | TRACE_EVENT_FLAG_HAS_LOCAL_ID |
406             TRACE_EVENT_FLAG_HAS_GLOBAL_ID | TRACE_EVENT_FLAG_ASYNC_TTS |
407             TRACE_EVENT_FLAG_BIND_TO_ENCLOSING | TRACE_EVENT_FLAG_FLOW_IN |
408             TRACE_EVENT_FLAG_FLOW_OUT | TRACE_EVENT_FLAG_HAS_PROCESS_ID);
409   }
410 
SetLegacyFlags(protos::pbzero::TrackEvent::LegacyEvent * legacy_event,char phase,uint32_t flags)411   static void SetLegacyFlags(
412       protos::pbzero::TrackEvent::LegacyEvent* legacy_event,
413       char phase,
414       uint32_t flags) {
415     if (PhaseToType(phase) == protos::pbzero::TrackEvent::TYPE_UNSPECIFIED)
416       legacy_event->set_phase(phase);
417     if (flags & TRACE_EVENT_FLAG_ASYNC_TTS)
418       legacy_event->set_use_async_tts(true);
419     if (flags & TRACE_EVENT_FLAG_BIND_TO_ENCLOSING)
420       legacy_event->set_bind_to_enclosing(true);
421 
422     const auto kFlowIn = TRACE_EVENT_FLAG_FLOW_IN;
423     const auto kFlowOut = TRACE_EVENT_FLAG_FLOW_OUT;
424     const auto kFlowInOut = kFlowIn | kFlowOut;
425     if ((flags & kFlowInOut) == kFlowInOut) {
426       legacy_event->set_flow_direction(
427           protos::pbzero::TrackEvent::LegacyEvent::FLOW_INOUT);
428     } else if (flags & kFlowIn) {
429       legacy_event->set_flow_direction(
430           protos::pbzero::TrackEvent::LegacyEvent::FLOW_IN);
431     } else if (flags & kFlowOut) {
432       legacy_event->set_flow_direction(
433           protos::pbzero::TrackEvent::LegacyEvent::FLOW_OUT);
434     }
435   }
436 };
437 
438 }  // namespace internal
439 }  // namespace perfetto
440 
441 // Implementations for the INTERNAL_* adapter macros used by the trace points
442 // below.
443 #define PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(phase, category, name, track, \
444                                                 ...)                          \
445   PERFETTO_INTERNAL_TRACK_EVENT(                                              \
446       category,                                                               \
447       ::perfetto::internal::GetStaticString(::perfetto::StaticString{name}),  \
448       ::perfetto::internal::TrackEventLegacy::PhaseToType(phase), track,      \
449       ##__VA_ARGS__);
450 
451 // The main entrypoint for writing unscoped legacy events.  This macro
452 // determines the right track to write the event on based on |flags| and
453 // |thread_id|.
454 #define PERFETTO_INTERNAL_LEGACY_EVENT(phase, category, name, flags,         \
455                                        thread_id, ...)                       \
456   [&]() {                                                                    \
457     constexpr auto& kDefaultTrack =                                          \
458         ::perfetto::internal::TrackEventInternal::kDefaultTrack;             \
459     /* First check the scope for instant events. */                          \
460     if ((phase) == TRACE_EVENT_PHASE_INSTANT) {                              \
461       /* Note: Avoids the need to set LegacyEvent::instant_event_scope. */   \
462       auto scope = (flags)&TRACE_EVENT_FLAG_SCOPE_MASK;                      \
463       switch (scope) {                                                       \
464         case TRACE_EVENT_SCOPE_GLOBAL:                                       \
465           PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(                           \
466               phase, category, name, ::perfetto::Track::Global(0),           \
467               ##__VA_ARGS__);                                                \
468           return;                                                            \
469         case TRACE_EVENT_SCOPE_PROCESS:                                      \
470           PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(                           \
471               phase, category, name, ::perfetto::ProcessTrack::Current(),    \
472               ##__VA_ARGS__);                                                \
473           return;                                                            \
474         default:                                                             \
475         case TRACE_EVENT_SCOPE_THREAD:                                       \
476           /* Fallthrough. */                                                 \
477           break;                                                             \
478       }                                                                      \
479     }                                                                        \
480     /* If an event targets the current thread or another process, write      \
481      * it on the current thread's track. The process override case is        \
482      * handled through |pid_override| in WriteLegacyEvent. */                \
483     if (std::is_same<                                                        \
484             decltype(thread_id),                                             \
485             ::perfetto::legacy::PerfettoLegacyCurrentThreadId>::value ||     \
486         ((flags)&TRACE_EVENT_FLAG_HAS_PROCESS_ID)) {                         \
487       PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(phase, category, name,         \
488                                               kDefaultTrack, ##__VA_ARGS__); \
489     } else {                                                                 \
490       PERFETTO_INTERNAL_LEGACY_EVENT_ON_TRACK(                               \
491           phase, category, name,                                             \
492           ::perfetto::legacy::ConvertThreadId(thread_id), ##__VA_ARGS__);    \
493     }                                                                        \
494   }()
495 
496 #define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...)        \
497   PERFETTO_INTERNAL_LEGACY_EVENT(                                          \
498       phase, category, name, flags, ::perfetto::legacy::kCurrentThreadId,  \
499       [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS { \
500         using ::perfetto::internal::TrackEventLegacy;                      \
501         TrackEventLegacy::WriteLegacyEvent(std::move(ctx), phase, flags,   \
502                                            ##__VA_ARGS__);                 \
503       })
504 
505 // PERFETTO_INTERNAL_SCOPED_TRACK_EVENT does not require GetStaticString, as it
506 // uses TRACE_EVENT_BEGIN/END internally, which already have this call.
507 #define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...)               \
508   PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(                                    \
509       category, ::perfetto::StaticString{name},                            \
510       [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS { \
511         using ::perfetto::internal::TrackEventLegacy;                      \
512         TrackEventLegacy::AddDebugAnnotations(&ctx, ##__VA_ARGS__);        \
513       })
514 
515 // PERFETTO_INTERNAL_SCOPED_TRACK_EVENT does not require GetStaticString, as it
516 // uses TRACE_EVENT_BEGIN/END internally, which already have this call.
517 #define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category, name, bind_id,   \
518                                                   flags, ...)                \
519   PERFETTO_INTERNAL_SCOPED_TRACK_EVENT(                                      \
520       category, ::perfetto::StaticString{name},                              \
521       [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {   \
522         using ::perfetto::internal::TrackEventLegacy;                        \
523         ::perfetto::internal::LegacyTraceId PERFETTO_UID(trace_id){bind_id}; \
524         TrackEventLegacy::WriteLegacyEventWithIdAndTid(                      \
525             std::move(ctx), TRACE_EVENT_PHASE_BEGIN, flags,                  \
526             PERFETTO_UID(trace_id), TRACE_EVENT_API_CURRENT_THREAD_ID,       \
527             ##__VA_ARGS__);                                                  \
528       })
529 
530 #define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category, name,     \
531                                                 timestamp, flags, ...)     \
532   PERFETTO_INTERNAL_LEGACY_EVENT(                                          \
533       phase, category, name, flags, ::perfetto::legacy::kCurrentThreadId,  \
534       timestamp,                                                           \
535       [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS { \
536         using ::perfetto::internal::TrackEventLegacy;                      \
537         TrackEventLegacy::WriteLegacyEvent(std::move(ctx), phase, flags,   \
538                                            ##__VA_ARGS__);                 \
539       })
540 
541 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                  \
542     phase, category, name, id, thread_id, timestamp, flags, ...)             \
543   PERFETTO_INTERNAL_LEGACY_EVENT(                                            \
544       phase, category, name, flags, thread_id, timestamp,                    \
545       [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS {   \
546         using ::perfetto::internal::TrackEventLegacy;                        \
547         ::perfetto::internal::LegacyTraceId PERFETTO_UID(trace_id){id};      \
548         TrackEventLegacy::WriteLegacyEventWithIdAndTid(                      \
549             std::move(ctx), phase, flags, PERFETTO_UID(trace_id), thread_id, \
550             ##__VA_ARGS__);                                                  \
551       })
552 
553 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags, \
554                                          ...)                              \
555   PERFETTO_INTERNAL_LEGACY_EVENT(                                          \
556       phase, category, name, flags, ::perfetto::legacy::kCurrentThreadId,  \
557       [&](perfetto::EventContext ctx) PERFETTO_NO_THREAD_SAFETY_ANALYSIS { \
558         using ::perfetto::internal::TrackEventLegacy;                      \
559         ::perfetto::internal::LegacyTraceId PERFETTO_UID(trace_id){id};    \
560         TrackEventLegacy::WriteLegacyEventWithIdAndTid(                    \
561             std::move(ctx), phase, flags, PERFETTO_UID(trace_id),          \
562             TRACE_EVENT_API_CURRENT_THREAD_ID, ##__VA_ARGS__);             \
563       })
564 
565 #define INTERNAL_TRACE_EVENT_METADATA_ADD(category, name, ...)         \
566   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_METADATA, category, name, \
567                            TRACE_EVENT_FLAG_NONE)
568 
569 // ----------------------------------------------------------------------------
570 // Legacy tracing common API (adapted from trace_event_common.h).
571 // ----------------------------------------------------------------------------
572 
573 #define TRACE_DISABLED_BY_DEFAULT(name) "disabled-by-default-" name
574 
575 // Scoped events.
576 #define TRACE_EVENT0(category_group, name) \
577   INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name)
578 #define TRACE_EVENT_WITH_FLOW0(category_group, name, bind_id, flow_flags)  \
579   INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, bind_id, \
580                                             flow_flags)
581 #define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
582   INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val)
583 #define TRACE_EVENT_WITH_FLOW1(category_group, name, bind_id, flow_flags,  \
584                                arg1_name, arg1_val)                        \
585   INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, bind_id, \
586                                             flow_flags, arg1_name, arg1_val)
587 #define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name,   \
588                      arg2_val)                                               \
589   INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val, \
590                                   arg2_name, arg2_val)
591 #define TRACE_EVENT_WITH_FLOW2(category_group, name, bind_id, flow_flags,    \
592                                arg1_name, arg1_val, arg2_name, arg2_val)     \
593   INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, bind_id,   \
594                                             flow_flags, arg1_name, arg1_val, \
595                                             arg2_name, arg2_val)
596 
597 // Instant events.
598 #define TRACE_EVENT_INSTANT0(category_group, name, scope)                   \
599   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
600                            TRACE_EVENT_FLAG_NONE | scope)
601 #define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \
602   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
603                            TRACE_EVENT_FLAG_NONE | scope, arg1_name, arg1_val)
604 #define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \
605                              arg2_name, arg2_val)                              \
606   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
607                            TRACE_EVENT_FLAG_NONE | scope, arg1_name, arg1_val, \
608                            arg2_name, arg2_val)
609 #define TRACE_EVENT_COPY_INSTANT0(category_group, name, scope)              \
610   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
611                            TRACE_EVENT_FLAG_COPY | scope)
612 #define TRACE_EVENT_COPY_INSTANT1(category_group, name, scope, arg1_name,   \
613                                   arg1_val)                                 \
614   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name, \
615                            TRACE_EVENT_FLAG_COPY | scope, arg1_name, arg1_val)
616 #define TRACE_EVENT_COPY_INSTANT2(category_group, name, scope, arg1_name,      \
617                                   arg1_val, arg2_name, arg2_val)               \
618   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
619                            TRACE_EVENT_FLAG_COPY | scope, arg1_name, arg1_val, \
620                            arg2_name, arg2_val)
621 #define TRACE_EVENT_INSTANT_WITH_FLAGS0(category_group, name, scope_and_flags) \
622   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
623                            scope_and_flags)
624 #define TRACE_EVENT_INSTANT_WITH_FLAGS1(category_group, name, scope_and_flags, \
625                                         arg1_name, arg1_val)                   \
626   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, category_group, name,    \
627                            scope_and_flags, arg1_name, arg1_val)
628 
629 // Instant events with explicit timestamps.
630 #define TRACE_EVENT_INSTANT_WITH_TIMESTAMP0(category_group, name, scope,   \
631                                             timestamp)                     \
632   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(TRACE_EVENT_PHASE_INSTANT,       \
633                                           category_group, name, timestamp, \
634                                           TRACE_EVENT_FLAG_NONE | scope)
635 
636 #define TRACE_EVENT_INSTANT_WITH_TIMESTAMP1(category_group, name, scope,  \
637                                             timestamp, arg_name, arg_val) \
638   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                \
639       TRACE_EVENT_PHASE_INSTANT, category_group, name, timestamp,         \
640       TRACE_EVENT_FLAG_NONE | scope, arg_name, arg_val)
641 
642 // Begin events.
643 #define TRACE_EVENT_BEGIN0(category_group, name)                          \
644   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
645                            TRACE_EVENT_FLAG_NONE)
646 #define TRACE_EVENT_BEGIN1(category_group, name, arg1_name, arg1_val)     \
647   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
648                            TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
649 #define TRACE_EVENT_BEGIN2(category_group, name, arg1_name, arg1_val,     \
650                            arg2_name, arg2_val)                           \
651   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, \
652                            TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val,    \
653                            arg2_name, arg2_val)
654 #define TRACE_EVENT_BEGIN_WITH_FLAGS0(category_group, name, flags) \
655   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name, flags)
656 #define TRACE_EVENT_BEGIN_WITH_FLAGS1(category_group, name, flags, arg1_name, \
657                                       arg1_val)                               \
658   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name,     \
659                            flags, arg1_name, arg1_val)
660 #define TRACE_EVENT_COPY_BEGIN2(category_group, name, arg1_name, arg1_val, \
661                                 arg2_name, arg2_val)                       \
662   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, category_group, name,  \
663                            TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val,     \
664                            arg2_name, arg2_val)
665 
666 // Begin events with explicit timestamps.
667 #define TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(category_group, name, id, \
668                                                      thread_id, timestamp)     \
669   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
670       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id,      \
671       timestamp, TRACE_EVENT_FLAG_NONE)
672 #define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(                \
673     category_group, name, id, thread_id, timestamp)                       \
674   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                     \
675       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \
676       timestamp, TRACE_EVENT_FLAG_COPY)
677 #define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP1(                \
678     category_group, name, id, thread_id, timestamp, arg1_name, arg1_val)  \
679   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                     \
680       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \
681       timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
682 #define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP2(                \
683     category_group, name, id, thread_id, timestamp, arg1_name, arg1_val,  \
684     arg2_name, arg2_val)                                                  \
685   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                     \
686       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \
687       timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name,   \
688       arg2_val)
689 
690 // End events.
691 #define TRACE_EVENT_END0(category_group, name)                          \
692   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
693                            TRACE_EVENT_FLAG_NONE)
694 #define TRACE_EVENT_END1(category_group, name, arg1_name, arg1_val)     \
695   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, \
696                            TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
697 #define TRACE_EVENT_END2(category_group, name, arg1_name, arg1_val, arg2_name, \
698                          arg2_val)                                             \
699   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name,        \
700                            TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val,         \
701                            arg2_name, arg2_val)
702 #define TRACE_EVENT_END_WITH_FLAGS0(category_group, name, flags) \
703   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, flags)
704 #define TRACE_EVENT_END_WITH_FLAGS1(category_group, name, flags, arg1_name,    \
705                                     arg1_val)                                  \
706   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name, flags, \
707                            arg1_name, arg1_val)
708 #define TRACE_EVENT_COPY_END2(category_group, name, arg1_name, arg1_val, \
709                               arg2_name, arg2_val)                       \
710   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, category_group, name,  \
711                            TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val,   \
712                            arg2_name, arg2_val)
713 
714 // Mark events.
715 #define TRACE_EVENT_MARK_WITH_TIMESTAMP0(category_group, name, timestamp)  \
716   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(TRACE_EVENT_PHASE_MARK,          \
717                                           category_group, name, timestamp, \
718                                           TRACE_EVENT_FLAG_NONE)
719 
720 #define TRACE_EVENT_MARK_WITH_TIMESTAMP1(category_group, name, timestamp, \
721                                          arg1_name, arg1_val)             \
722   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                \
723       TRACE_EVENT_PHASE_MARK, category_group, name, timestamp,            \
724       TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
725 
726 #define TRACE_EVENT_MARK_WITH_TIMESTAMP2(                                      \
727     category_group, name, timestamp, arg1_name, arg1_val, arg2_name, arg2_val) \
728   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                     \
729       TRACE_EVENT_PHASE_MARK, category_group, name, timestamp,                 \
730       TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
731 
732 #define TRACE_EVENT_COPY_MARK(category_group, name)                      \
733   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_MARK, category_group, name, \
734                            TRACE_EVENT_FLAG_COPY)
735 
736 #define TRACE_EVENT_COPY_MARK1(category_group, name, arg1_name, arg1_val) \
737   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_MARK, category_group, name,  \
738                            TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
739 
740 #define TRACE_EVENT_COPY_MARK_WITH_TIMESTAMP(category_group, name, timestamp) \
741   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(TRACE_EVENT_PHASE_MARK,             \
742                                           category_group, name, timestamp,    \
743                                           TRACE_EVENT_FLAG_COPY)
744 
745 // End events with explicit thread and timestamp.
746 #define TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0(category_group, name, id, \
747                                                    thread_id, timestamp)     \
748   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                        \
749       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id,      \
750       timestamp, TRACE_EVENT_FLAG_NONE)
751 #define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0(                \
752     category_group, name, id, thread_id, timestamp)                     \
753   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                   \
754       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id, \
755       timestamp, TRACE_EVENT_FLAG_COPY)
756 #define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP1(                 \
757     category_group, name, id, thread_id, timestamp, arg1_name, arg1_val) \
758   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                    \
759       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id,  \
760       timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
761 #define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP2(                 \
762     category_group, name, id, thread_id, timestamp, arg1_name, arg1_val, \
763     arg2_name, arg2_val)                                                 \
764   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                    \
765       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id,  \
766       timestamp, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name,  \
767       arg2_val)
768 
769 // Counters.
770 #define TRACE_COUNTER1(category_group, name, value)                         \
771   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
772                            TRACE_EVENT_FLAG_NONE, "value",                  \
773                            static_cast<int>(value))
774 #define TRACE_COUNTER_WITH_FLAG1(category_group, name, flag, value)         \
775   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
776                            flag, "value", static_cast<int>(value))
777 #define TRACE_COPY_COUNTER1(category_group, name, value)                    \
778   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
779                            TRACE_EVENT_FLAG_COPY, "value",                  \
780                            static_cast<int>(value))
781 #define TRACE_COUNTER2(category_group, name, value1_name, value1_val,       \
782                        value2_name, value2_val)                             \
783   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
784                            TRACE_EVENT_FLAG_NONE, value1_name,              \
785                            static_cast<int>(value1_val), value2_name,       \
786                            static_cast<int>(value2_val))
787 #define TRACE_COPY_COUNTER2(category_group, name, value1_name, value1_val,  \
788                             value2_name, value2_val)                        \
789   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, category_group, name, \
790                            TRACE_EVENT_FLAG_COPY, value1_name,              \
791                            static_cast<int>(value1_val), value2_name,       \
792                            static_cast<int>(value2_val))
793 
794 // Counters with explicit timestamps.
795 #define TRACE_COUNTER_WITH_TIMESTAMP1(category_group, name, timestamp, value) \
796   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                    \
797       TRACE_EVENT_PHASE_COUNTER, category_group, name, timestamp,             \
798       TRACE_EVENT_FLAG_NONE, "value", static_cast<int>(value))
799 
800 #define TRACE_COUNTER_WITH_TIMESTAMP2(category_group, name, timestamp,      \
801                                       value1_name, value1_val, value2_name, \
802                                       value2_val)                           \
803   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                  \
804       TRACE_EVENT_PHASE_COUNTER, category_group, name, timestamp,           \
805       TRACE_EVENT_FLAG_NONE, value1_name, static_cast<int>(value1_val),     \
806       value2_name, static_cast<int>(value2_val))
807 
808 // Counters with ids.
809 #define TRACE_COUNTER_ID1(category_group, name, id, value)                    \
810   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
811                                    name, id, TRACE_EVENT_FLAG_NONE, "value",  \
812                                    static_cast<int>(value))
813 #define TRACE_COPY_COUNTER_ID1(category_group, name, id, value)               \
814   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
815                                    name, id, TRACE_EVENT_FLAG_COPY, "value",  \
816                                    static_cast<int>(value))
817 #define TRACE_COUNTER_ID2(category_group, name, id, value1_name, value1_val,  \
818                           value2_name, value2_val)                            \
819   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
820                                    name, id, TRACE_EVENT_FLAG_NONE,           \
821                                    value1_name, static_cast<int>(value1_val), \
822                                    value2_name, static_cast<int>(value2_val))
823 #define TRACE_COPY_COUNTER_ID2(category_group, name, id, value1_name,         \
824                                value1_val, value2_name, value2_val)           \
825   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, category_group, \
826                                    name, id, TRACE_EVENT_FLAG_COPY,           \
827                                    value1_name, static_cast<int>(value1_val), \
828                                    value2_name, static_cast<int>(value2_val))
829 
830 // Sampling profiler events.
831 #define TRACE_EVENT_SAMPLE_WITH_ID1(category_group, name, id, arg1_name,       \
832                                     arg1_val)                                  \
833   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_SAMPLE, category_group,   \
834                                    name, id, TRACE_EVENT_FLAG_NONE, arg1_name, \
835                                    arg1_val)
836 
837 // Legacy async events.
838 #define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id)        \
839   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
840                                    category_group, name, id,      \
841                                    TRACE_EVENT_FLAG_NONE)
842 #define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
843                                  arg1_val)                            \
844   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN,     \
845                                    category_group, name, id,          \
846                                    TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
847 #define TRACE_EVENT_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
848                                  arg1_val, arg2_name, arg2_val)       \
849   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                   \
850       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,        \
851       TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
852 #define TRACE_EVENT_COPY_ASYNC_BEGIN0(category_group, name, id)   \
853   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
854                                    category_group, name, id,      \
855                                    TRACE_EVENT_FLAG_COPY)
856 #define TRACE_EVENT_COPY_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
857                                       arg1_val)                            \
858   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN,          \
859                                    category_group, name, id,               \
860                                    TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
861 #define TRACE_EVENT_COPY_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
862                                       arg1_val, arg2_name, arg2_val)       \
863   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                        \
864       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,             \
865       TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val)
866 #define TRACE_EVENT_ASYNC_BEGIN_WITH_FLAGS0(category_group, name, id, flags) \
867   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN,            \
868                                    category_group, name, id, flags)
869 
870 // Legacy async events with explicit timestamps.
871 #define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, id, \
872                                                 timestamp)                \
873   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                     \
874       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,            \
875       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
876 #define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(                           \
877     category_group, name, id, timestamp, arg1_name, arg1_val)              \
878   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
879       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,             \
880       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
881       arg1_name, arg1_val)
882 #define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP2(category_group, name, id,      \
883                                                 timestamp, arg1_name,          \
884                                                 arg1_val, arg2_name, arg2_val) \
885   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
886       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,                 \
887       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,     \
888       arg1_name, arg1_val, arg2_name, arg2_val)
889 #define TRACE_EVENT_COPY_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, id, \
890                                                      timestamp)                \
891   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
892       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id,                 \
893       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
894 #define TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP_AND_FLAGS0(     \
895     category_group, name, id, timestamp, flags)                \
896   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(          \
897       TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, \
898       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
899 
900 // Legacy async step into events.
901 #define TRACE_EVENT_ASYNC_STEP_INTO0(category_group, name, id, step)  \
902   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP_INTO, \
903                                    category_group, name, id,          \
904                                    TRACE_EVENT_FLAG_NONE, "step", step)
905 #define TRACE_EVENT_ASYNC_STEP_INTO1(category_group, name, id, step, \
906                                      arg1_name, arg1_val)            \
907   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                  \
908       TRACE_EVENT_PHASE_ASYNC_STEP_INTO, category_group, name, id,   \
909       TRACE_EVENT_FLAG_NONE, "step", step, arg1_name, arg1_val)
910 
911 // Legacy async step into events with timestamps.
912 #define TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(category_group, name, id, \
913                                                     step, timestamp)          \
914   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
915       TRACE_EVENT_PHASE_ASYNC_STEP_INTO, category_group, name, id,            \
916       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,    \
917       "step", step)
918 
919 // Legacy async step past events.
920 #define TRACE_EVENT_ASYNC_STEP_PAST0(category_group, name, id, step)  \
921   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP_PAST, \
922                                    category_group, name, id,          \
923                                    TRACE_EVENT_FLAG_NONE, "step", step)
924 #define TRACE_EVENT_ASYNC_STEP_PAST1(category_group, name, id, step, \
925                                      arg1_name, arg1_val)            \
926   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                  \
927       TRACE_EVENT_PHASE_ASYNC_STEP_PAST, category_group, name, id,   \
928       TRACE_EVENT_FLAG_NONE, "step", step, arg1_name, arg1_val)
929 
930 // Legacy async end events.
931 #define TRACE_EVENT_ASYNC_END0(category_group, name, id)        \
932   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
933                                    category_group, name, id,    \
934                                    TRACE_EVENT_FLAG_NONE)
935 #define TRACE_EVENT_ASYNC_END1(category_group, name, id, arg1_name, arg1_val) \
936   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END,               \
937                                    category_group, name, id,                  \
938                                    TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
939 #define TRACE_EVENT_ASYNC_END2(category_group, name, id, arg1_name, arg1_val, \
940                                arg2_name, arg2_val)                           \
941   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                           \
942       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
943       TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
944 #define TRACE_EVENT_COPY_ASYNC_END0(category_group, name, id)   \
945   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
946                                    category_group, name, id,    \
947                                    TRACE_EVENT_FLAG_COPY)
948 #define TRACE_EVENT_COPY_ASYNC_END1(category_group, name, id, arg1_name, \
949                                     arg1_val)                            \
950   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END,          \
951                                    category_group, name, id,             \
952                                    TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
953 #define TRACE_EVENT_COPY_ASYNC_END2(category_group, name, id, arg1_name, \
954                                     arg1_val, arg2_name, arg2_val)       \
955   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                      \
956       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,             \
957       TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, arg2_name, arg2_val)
958 #define TRACE_EVENT_ASYNC_END_WITH_FLAGS0(category_group, name, id, flags) \
959   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END,            \
960                                    category_group, name, id, flags)
961 
962 // Legacy async end events with explicit timestamps.
963 #define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP0(category_group, name, id, \
964                                               timestamp)                \
965   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                   \
966       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,            \
967       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
968 #define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP1(category_group, name, id,       \
969                                               timestamp, arg1_name, arg1_val) \
970   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
971       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
972       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,    \
973       arg1_name, arg1_val)
974 #define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP2(category_group, name, id,       \
975                                               timestamp, arg1_name, arg1_val, \
976                                               arg2_name, arg2_val)            \
977   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
978       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
979       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE,    \
980       arg1_name, arg1_val, arg2_name, arg2_val)
981 #define TRACE_EVENT_COPY_ASYNC_END_WITH_TIMESTAMP0(category_group, name, id, \
982                                                    timestamp)                \
983   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                        \
984       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                 \
985       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
986 #define TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP_AND_FLAGS0(category_group, name, \
987                                                         id, timestamp, flags) \
988   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                         \
989       TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id,                  \
990       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, flags)
991 
992 // Async events.
993 #define TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(category_group, name, id)        \
994   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
995                                    category_group, name, id,               \
996                                    TRACE_EVENT_FLAG_NONE)
997 #define TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
998                                           arg1_val)                            \
999   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN,     \
1000                                    category_group, name, id,                   \
1001                                    TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
1002 #define TRACE_EVENT_NESTABLE_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
1003                                           arg1_val, arg2_name, arg2_val)       \
1004   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                            \
1005       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,        \
1006       TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
1007 #define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP1(                  \
1008     category_group, name, id, timestamp, arg1_name, arg1_val)              \
1009   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
1010       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,    \
1011       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
1012       arg1_name, arg1_val)
1013 
1014 // Async end events.
1015 #define TRACE_EVENT_NESTABLE_ASYNC_END0(category_group, name, id)        \
1016   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
1017                                    category_group, name, id,             \
1018                                    TRACE_EVENT_FLAG_NONE)
1019 #define TRACE_EVENT_NESTABLE_ASYNC_END1(category_group, name, id, arg1_name, \
1020                                         arg1_val)                            \
1021   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END,     \
1022                                    category_group, name, id,                 \
1023                                    TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
1024 #define TRACE_EVENT_NESTABLE_ASYNC_END2(category_group, name, id, arg1_name, \
1025                                         arg1_val, arg2_name, arg2_val)       \
1026   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                          \
1027       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,        \
1028       TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
1029 
1030 // Async instant events.
1031 #define TRACE_EVENT_NESTABLE_ASYNC_INSTANT0(category_group, name, id)        \
1032   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, \
1033                                    category_group, name, id,                 \
1034                                    TRACE_EVENT_FLAG_NONE)
1035 #define TRACE_EVENT_NESTABLE_ASYNC_INSTANT1(category_group, name, id,        \
1036                                             arg1_name, arg1_val)             \
1037   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, \
1038                                    category_group, name, id,                 \
1039                                    TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
1040 #define TRACE_EVENT_NESTABLE_ASYNC_INSTANT2(                              \
1041     category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val)   \
1042   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                       \
1043       TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, category_group, name, id, \
1044       TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, arg2_name, arg2_val)
1045 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TTS2(                       \
1046     category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val)        \
1047   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                            \
1048       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,        \
1049       TRACE_EVENT_FLAG_ASYNC_TTS | TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
1050       arg2_name, arg2_val)
1051 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TTS2(                         \
1052     category_group, name, id, arg1_name, arg1_val, arg2_name, arg2_val)        \
1053   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                            \
1054       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,          \
1055       TRACE_EVENT_FLAG_ASYNC_TTS | TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
1056       arg2_name, arg2_val)
1057 
1058 // Async events with explicit timestamps.
1059 #define TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(category_group, name, \
1060                                                          id, timestamp)        \
1061   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                          \
1062       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id,        \
1063       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
1064 #define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(category_group, name, \
1065                                                        id, timestamp)        \
1066   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                        \
1067       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,        \
1068       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
1069 #define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP1(                    \
1070     category_group, name, id, timestamp, arg1_name, arg1_val)              \
1071   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
1072       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,      \
1073       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
1074       arg1_name, arg1_val)
1075 #define TRACE_EVENT_NESTABLE_ASYNC_INSTANT_WITH_TIMESTAMP0(               \
1076     category_group, name, id, timestamp)                                  \
1077   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                     \
1078       TRACE_EVENT_PHASE_NESTABLE_ASYNC_INSTANT, category_group, name, id, \
1079       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE)
1080 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN0(category_group, name, id)   \
1081   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, \
1082                                    category_group, name, id,               \
1083                                    TRACE_EVENT_FLAG_COPY)
1084 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_END0(category_group, name, id)   \
1085   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, \
1086                                    category_group, name, id,             \
1087                                    TRACE_EVENT_FLAG_COPY)
1088 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP0(          \
1089     category_group, name, id, timestamp)                                \
1090   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                   \
1091       TRACE_EVENT_PHASE_NESTABLE_ASYNC_BEGIN, category_group, name, id, \
1092       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
1093 #define TRACE_EVENT_COPY_NESTABLE_ASYNC_END_WITH_TIMESTAMP0(          \
1094     category_group, name, id, timestamp)                              \
1095   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                 \
1096       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id, \
1097       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_COPY)
1098 #define TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP2(                    \
1099     category_group, name, id, timestamp, arg1_name, arg1_val, arg2_name,   \
1100     arg2_val)                                                              \
1101   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
1102       TRACE_EVENT_PHASE_NESTABLE_ASYNC_END, category_group, name, id,      \
1103       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
1104       arg1_name, arg1_val, arg2_name, arg2_val)
1105 
1106 // Metadata events.
1107 #define TRACE_EVENT_METADATA1(category_group, name, arg1_name, arg1_val) \
1108   INTERNAL_TRACE_EVENT_METADATA_ADD(category_group, name, arg1_name, arg1_val)
1109 
1110 // Clock sync events.
1111 #define TRACE_EVENT_CLOCK_SYNC_RECEIVER(sync_id)                           \
1112   INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_CLOCK_SYNC, "__metadata",     \
1113                            "clock_sync", TRACE_EVENT_FLAG_NONE, "sync_id", \
1114                            sync_id)
1115 #define TRACE_EVENT_CLOCK_SYNC_ISSUER(sync_id, issue_ts, issue_end_ts)        \
1116   INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(                                    \
1117       TRACE_EVENT_PHASE_CLOCK_SYNC, "__metadata", "clock_sync", issue_end_ts, \
1118       TRACE_EVENT_FLAG_NONE, "sync_id", sync_id, "issue_ts", issue_ts)
1119 
1120 // Object events.
1121 #define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) \
1122   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_CREATE_OBJECT,  \
1123                                    category_group, name, id,         \
1124                                    TRACE_EVENT_FLAG_NONE)
1125 
1126 #define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, \
1127                                             snapshot)                 \
1128   INTERNAL_TRACE_EVENT_ADD_WITH_ID(                                   \
1129       TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, category_group, name, id,    \
1130       TRACE_EVENT_FLAG_NONE, "snapshot", snapshot)
1131 
1132 #define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID_AND_TIMESTAMP(                 \
1133     category_group, name, id, timestamp, snapshot)                         \
1134   INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(                      \
1135       TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, category_group, name, id,         \
1136       TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, TRACE_EVENT_FLAG_NONE, \
1137       "snapshot", snapshot)
1138 
1139 #define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) \
1140   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_DELETE_OBJECT,  \
1141                                    category_group, name, id,         \
1142                                    TRACE_EVENT_FLAG_NONE)
1143 
1144 // Context events.
1145 #define TRACE_EVENT_ENTER_CONTEXT(category_group, name, context)    \
1146   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ENTER_CONTEXT, \
1147                                    category_group, name, context,   \
1148                                    TRACE_EVENT_FLAG_NONE)
1149 #define TRACE_EVENT_LEAVE_CONTEXT(category_group, name, context)    \
1150   INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_LEAVE_CONTEXT, \
1151                                    category_group, name, context,   \
1152                                    TRACE_EVENT_FLAG_NONE)
1153 
1154 // TODO(skyostil): Implement binary-efficient trace events.
1155 #define TRACE_EVENT_BINARY_EFFICIENT0 TRACE_EVENT0
1156 #define TRACE_EVENT_BINARY_EFFICIENT1 TRACE_EVENT1
1157 #define TRACE_EVENT_BINARY_EFFICIENT2 TRACE_EVENT2
1158 
1159 // Macro to efficiently determine if a given category group is enabled.
1160 #define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category, ret) \
1161   do {                                                    \
1162     *ret = TRACE_EVENT_CATEGORY_ENABLED(category);        \
1163   } while (0)
1164 
1165 // Macro to efficiently determine, through polling, if a new trace has begun.
1166 #define TRACE_EVENT_IS_NEW_TRACE(ret)                                \
1167   do {                                                               \
1168     static int PERFETTO_UID(prev) = -1;                              \
1169     int PERFETTO_UID(curr) =                                         \
1170         ::perfetto::internal::TrackEventInternal::GetSessionCount(); \
1171     if (::PERFETTO_TRACK_EVENT_NAMESPACE::TrackEvent::IsEnabled() && \
1172         (PERFETTO_UID(prev) != PERFETTO_UID(curr))) {                \
1173       *(ret) = true;                                                 \
1174       PERFETTO_UID(prev) = PERFETTO_UID(curr);                       \
1175     } else {                                                         \
1176       *(ret) = false;                                                \
1177     }                                                                \
1178   } while (0)
1179 
1180 // ----------------------------------------------------------------------------
1181 // Legacy tracing API (adapted from trace_event.h).
1182 // ----------------------------------------------------------------------------
1183 
1184 // We can implement the following subset of the legacy tracing API without
1185 // involvement from the embedder. APIs such as TRACE_EVENT_API_ADD_TRACE_EVENT
1186 // are still up to the embedder to define.
1187 
1188 #define TRACE_STR_COPY(str) (str)
1189 
1190 #define TRACE_ID_WITH_SCOPE(scope, ...) \
1191   ::perfetto::internal::LegacyTraceId::WithScope(scope, ##__VA_ARGS__)
1192 
1193 // Use this for ids that are unique across processes. This allows different
1194 // processes to use the same id to refer to the same event.
1195 #define TRACE_ID_GLOBAL(id) ::perfetto::internal::LegacyTraceId::GlobalId(id)
1196 
1197 // Use this for ids that are unique within a single process. This allows
1198 // different processes to use the same id to refer to different events.
1199 #define TRACE_ID_LOCAL(id) ::perfetto::internal::LegacyTraceId::LocalId(id)
1200 
1201 // Returns a pointer to a uint8_t which indicates whether tracing is enabled for
1202 // the given category or not. A zero value means tracing is disabled and
1203 // non-zero indicates at least one tracing session for this category is active.
1204 // Note that callers should not make any assumptions at what each bit represents
1205 // in the status byte. Does not support dynamic categories.
1206 #define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category)                \
1207   reinterpret_cast<const uint8_t*>(                                         \
1208       [&] {                                                                 \
1209         static_assert(                                                      \
1210             !std::is_same<::perfetto::DynamicCategory,                      \
1211                           decltype(category)>::value,                       \
1212             "Enabled flag pointers are not supported for dynamic trace "    \
1213             "categories.");                                                 \
1214       },                                                                    \
1215       PERFETTO_TRACK_EVENT_NAMESPACE::internal::kConstExprCategoryRegistry  \
1216           .GetCategoryState(                                                \
1217               ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
1218                   .Find(category, /*is_dynamic=*/false)))
1219 
1220 // Given a pointer returned by TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED,
1221 // yields a pointer to the name of the corresponding category group.
1222 #define TRACE_EVENT_API_GET_CATEGORY_GROUP_NAME(category_enabled_ptr)       \
1223   ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kConstExprCategoryRegistry    \
1224       .GetCategory(                                                         \
1225           category_enabled_ptr -                                            \
1226           reinterpret_cast<const uint8_t*>(                                 \
1227               ::PERFETTO_TRACK_EVENT_NAMESPACE::internal::kCategoryRegistry \
1228                   .GetCategoryState(0u)))                                   \
1229       ->name
1230 
1231 #endif  // PERFETTO_ENABLE_LEGACY_TRACE_EVENTS
1232 
1233 #endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_LEGACY_H_
1234