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