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