1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_TRACE_EVENT_TRACE_EVENT_H_ 6 #define BASE_TRACE_EVENT_TRACE_EVENT_H_ 7 8 // This header file defines implementation details of how the trace macros in 9 // trace_event_common.h collect and store trace events. Anything not 10 // implementation-specific should go in trace_event_common.h instead of here. 11 12 #include <stddef.h> 13 #include <stdint.h> 14 15 #include <string> 16 17 #include "base/atomicops.h" 18 #include "base/macros.h" 19 #include "base/time/time.h" 20 #include "base/trace_event/common/trace_event_common.h" 21 #include "base/trace_event/heap_profiler.h" 22 #include "base/trace_event/trace_category.h" 23 #include "base/trace_event/trace_event_system_stats_monitor.h" 24 #include "base/trace_event/trace_log.h" 25 #include "build/build_config.h" 26 27 // By default, const char* argument values are assumed to have long-lived scope 28 // and will not be copied. Use this macro to force a const char* to be copied. 29 #define TRACE_STR_COPY(str) \ 30 trace_event_internal::TraceStringWithCopy(str) 31 32 // DEPRECATED: do not use: Consider using TRACE_ID_{GLOBAL, LOCAL} macros, 33 // instead. By default, uint64_t ID argument values are not mangled with the 34 // Process ID in TRACE_EVENT_ASYNC macros. Use this macro to force Process ID 35 // mangling. 36 #define TRACE_ID_MANGLE(id) \ 37 trace_event_internal::TraceID::ForceMangle(id) 38 39 // DEPRECATED: do not use: Consider using TRACE_ID_{GLOBAL, LOCAL} macros, 40 // instead. By default, pointers are mangled with the Process ID in 41 // TRACE_EVENT_ASYNC macros. Use this macro to prevent Process ID mangling. 42 #define TRACE_ID_DONT_MANGLE(id) \ 43 trace_event_internal::TraceID::DontMangle(id) 44 45 // By default, trace IDs are eventually converted to a single 64-bit number. Use 46 // this macro to add a scope string. For example, 47 // 48 // TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( 49 // "network", "ResourceLoad", 50 // TRACE_ID_WITH_SCOPE("BlinkResourceID", resourceID)); 51 // 52 // Also, it is possible to prepend the ID with another number, like the process 53 // ID. This is useful in creatin IDs that are unique among all processes. To do 54 // that, pass two numbers after the scope string instead of one. For example, 55 // 56 // TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( 57 // "network", "ResourceLoad", 58 // TRACE_ID_WITH_SCOPE("BlinkResourceID", pid, resourceID)); 59 #define TRACE_ID_WITH_SCOPE(scope, ...) \ 60 trace_event_internal::TraceID::WithScope(scope, ##__VA_ARGS__) 61 62 #define TRACE_ID_GLOBAL(id) trace_event_internal::TraceID::GlobalId(id) 63 #define TRACE_ID_LOCAL(id) trace_event_internal::TraceID::LocalId(id) 64 65 #define TRACE_EVENT_API_CURRENT_THREAD_ID \ 66 static_cast<int>(base::PlatformThread::CurrentId()) 67 68 #define INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE() \ 69 UNLIKELY(*INTERNAL_TRACE_EVENT_UID(category_group_enabled) & \ 70 (base::trace_event::TraceCategory::ENABLED_FOR_RECORDING | \ 71 base::trace_event::TraceCategory::ENABLED_FOR_ETW_EXPORT)) 72 73 #define INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED() \ 74 UNLIKELY(*INTERNAL_TRACE_EVENT_UID(category_group_enabled) & \ 75 (base::trace_event::TraceCategory::ENABLED_FOR_RECORDING | \ 76 base::trace_event::TraceCategory::ENABLED_FOR_ETW_EXPORT | \ 77 base::trace_event::TraceCategory::ENABLED_FOR_FILTERING)) 78 79 //////////////////////////////////////////////////////////////////////////////// 80 // Implementation specific tracing API definitions. 81 82 // Get a pointer to the enabled state of the given trace category. Only 83 // long-lived literal strings should be given as the category group. The 84 // returned pointer can be held permanently in a local static for example. If 85 // the unsigned char is non-zero, tracing is enabled. If tracing is enabled, 86 // TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled 87 // between the load of the tracing state and the call to 88 // TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out 89 // for best performance when tracing is disabled. 90 // const unsigned char* 91 // TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(const char* category_group) 92 #define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \ 93 base::trace_event::TraceLog::GetCategoryGroupEnabled 94 95 // Get the number of times traces have been recorded. This is used to implement 96 // the TRACE_EVENT_IS_NEW_TRACE facility. 97 // unsigned int TRACE_EVENT_API_GET_NUM_TRACES_RECORDED() 98 #define TRACE_EVENT_API_GET_NUM_TRACES_RECORDED \ 99 base::trace_event::TraceLog::GetInstance()->GetNumTracesRecorded 100 101 // Add a trace event to the platform tracing system. 102 // base::trace_event::TraceEventHandle TRACE_EVENT_API_ADD_TRACE_EVENT( 103 // char phase, 104 // const unsigned char* category_group_enabled, 105 // const char* name, 106 // const char* scope, 107 // unsigned long long id, 108 // int num_args, 109 // const char** arg_names, 110 // const unsigned char* arg_types, 111 // const unsigned long long* arg_values, 112 // std::unique_ptr<ConvertableToTraceFormat>* 113 // convertable_values, 114 // unsigned int flags) 115 #define TRACE_EVENT_API_ADD_TRACE_EVENT \ 116 base::trace_event::TraceLog::GetInstance()->AddTraceEvent 117 118 // Add a trace event to the platform tracing system. 119 // base::trace_event::TraceEventHandle 120 // TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_BIND_ID( 121 // char phase, 122 // const unsigned char* category_group_enabled, 123 // const char* name, 124 // const char* scope, 125 // unsigned long long id, 126 // unsigned long long bind_id, 127 // int num_args, 128 // const char** arg_names, 129 // const unsigned char* arg_types, 130 // const unsigned long long* arg_values, 131 // std::unique_ptr<ConvertableToTraceFormat>* 132 // convertable_values, 133 // unsigned int flags) 134 #define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_BIND_ID \ 135 base::trace_event::TraceLog::GetInstance()->AddTraceEventWithBindId 136 137 // Add a trace event to the platform tracing system overriding the pid. 138 // The resulting event will have tid = pid == (process_id passed here). 139 // base::trace_event::TraceEventHandle 140 // TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID( 141 // char phase, 142 // const unsigned char* category_group_enabled, 143 // const char* name, 144 // const char* scope, 145 // unsigned long long id, 146 // int process_id, 147 // int num_args, 148 // const char** arg_names, 149 // const unsigned char* arg_types, 150 // const unsigned long long* arg_values, 151 // std::unique_ptr<ConvertableToTraceFormat>* 152 // convertable_values, 153 // unsigned int flags) 154 #define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_PROCESS_ID \ 155 base::trace_event::TraceLog::GetInstance()->AddTraceEventWithProcessId 156 157 // Add a trace event to the platform tracing system. 158 // base::trace_event::TraceEventHandle 159 // TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP( 160 // char phase, 161 // const unsigned char* category_group_enabled, 162 // const char* name, 163 // const char* scope, 164 // unsigned long long id, 165 // int thread_id, 166 // const TimeTicks& timestamp, 167 // int num_args, 168 // const char** arg_names, 169 // const unsigned char* arg_types, 170 // const unsigned long long* arg_values, 171 // std::unique_ptr<ConvertableToTraceFormat>* 172 // convertable_values, 173 // unsigned int flags) 174 #define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP \ 175 base::trace_event::TraceLog::GetInstance() \ 176 ->AddTraceEventWithThreadIdAndTimestamp 177 178 // Set the duration field of a COMPLETE trace event. 179 // void TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION( 180 // const unsigned char* category_group_enabled, 181 // const char* name, 182 // base::trace_event::TraceEventHandle id) 183 #define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION \ 184 base::trace_event::TraceLog::GetInstance()->UpdateTraceEventDuration 185 186 // Adds a metadata event to the trace log. The |AppendValueAsTraceFormat| method 187 // on the convertable value will be called at flush time. 188 // TRACE_EVENT_API_ADD_METADATA_EVENT( 189 // const unsigned char* category_group_enabled, 190 // const char* event_name, 191 // const char* arg_name, 192 // std::unique_ptr<ConvertableToTraceFormat> arg_value) 193 #define TRACE_EVENT_API_ADD_METADATA_EVENT \ 194 trace_event_internal::AddMetadataEvent 195 196 // Defines atomic operations used internally by the tracing system. 197 #define TRACE_EVENT_API_ATOMIC_WORD base::subtle::AtomicWord 198 #define TRACE_EVENT_API_ATOMIC_LOAD(var) base::subtle::NoBarrier_Load(&(var)) 199 #define TRACE_EVENT_API_ATOMIC_STORE(var, value) \ 200 base::subtle::NoBarrier_Store(&(var), (value)) 201 202 // Defines visibility for classes in trace_event.h 203 #define TRACE_EVENT_API_CLASS_EXPORT BASE_EXPORT 204 205 //////////////////////////////////////////////////////////////////////////////// 206 207 // Implementation detail: trace event macros create temporary variables 208 // to keep instrumentation overhead low. These macros give each temporary 209 // variable a unique name based on the line number to prevent name collisions. 210 #define INTERNAL_TRACE_EVENT_UID3(a,b) \ 211 trace_event_unique_##a##b 212 #define INTERNAL_TRACE_EVENT_UID2(a,b) \ 213 INTERNAL_TRACE_EVENT_UID3(a,b) 214 #define INTERNAL_TRACE_EVENT_UID(name_prefix) \ 215 INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__) 216 217 // Implementation detail: internal macro to create static category. 218 // No barriers are needed, because this code is designed to operate safely 219 // even when the unsigned char* points to garbage data (which may be the case 220 // on processors without cache coherency). 221 #define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES( \ 222 category_group, atomic, category_group_enabled) \ 223 category_group_enabled = \ 224 reinterpret_cast<const unsigned char*>(TRACE_EVENT_API_ATOMIC_LOAD( \ 225 atomic)); \ 226 if (UNLIKELY(!category_group_enabled)) { \ 227 category_group_enabled = \ 228 TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); \ 229 TRACE_EVENT_API_ATOMIC_STORE(atomic, \ 230 reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>( \ 231 category_group_enabled)); \ 232 } 233 234 #define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group) \ 235 static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) = 0; \ 236 const unsigned char* INTERNAL_TRACE_EVENT_UID(category_group_enabled); \ 237 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES(category_group, \ 238 INTERNAL_TRACE_EVENT_UID(atomic), \ 239 INTERNAL_TRACE_EVENT_UID(category_group_enabled)); 240 241 // Implementation detail: internal macro to create static category and add 242 // event if the category is enabled. 243 #define INTERNAL_TRACE_EVENT_ADD(phase, category_group, name, flags, ...) \ 244 do { \ 245 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ 246 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \ 247 trace_event_internal::AddTraceEvent( \ 248 phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ 249 trace_event_internal::kGlobalScope, trace_event_internal::kNoId, \ 250 flags, trace_event_internal::kNoId, ##__VA_ARGS__); \ 251 } \ 252 } while (0) 253 254 // Implementation detail: internal macro to create static category and add begin 255 // event if the category is enabled. Also adds the end event when the scope 256 // ends. 257 #define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...) \ 258 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ 259 trace_event_internal::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \ 260 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \ 261 base::trace_event::TraceEventHandle h = \ 262 trace_event_internal::AddTraceEvent( \ 263 TRACE_EVENT_PHASE_COMPLETE, \ 264 INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ 265 trace_event_internal::kGlobalScope, trace_event_internal::kNoId, \ 266 TRACE_EVENT_FLAG_NONE, trace_event_internal::kNoId, \ 267 ##__VA_ARGS__); \ 268 INTERNAL_TRACE_EVENT_UID(tracer).Initialize( \ 269 INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, h); \ 270 } 271 272 #define INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, \ 273 bind_id, flow_flags, ...) \ 274 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ 275 trace_event_internal::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \ 276 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \ 277 trace_event_internal::TraceID trace_event_bind_id((bind_id)); \ 278 unsigned int trace_event_flags = \ 279 flow_flags | trace_event_bind_id.id_flags(); \ 280 base::trace_event::TraceEventHandle h = \ 281 trace_event_internal::AddTraceEvent( \ 282 TRACE_EVENT_PHASE_COMPLETE, \ 283 INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ 284 trace_event_internal::kGlobalScope, trace_event_internal::kNoId, \ 285 trace_event_flags, trace_event_bind_id.raw_id(), ##__VA_ARGS__); \ 286 INTERNAL_TRACE_EVENT_UID(tracer).Initialize( \ 287 INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, h); \ 288 } 289 290 // Implementation detail: internal macro to create static category and add 291 // event if the category is enabled. 292 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category_group, name, id, \ 293 flags, ...) \ 294 do { \ 295 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ 296 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \ 297 trace_event_internal::TraceID trace_event_trace_id((id)); \ 298 unsigned int trace_event_flags = \ 299 flags | trace_event_trace_id.id_flags(); \ 300 trace_event_internal::AddTraceEvent( \ 301 phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ 302 trace_event_trace_id.scope(), trace_event_trace_id.raw_id(), \ 303 trace_event_flags, trace_event_internal::kNoId, ##__VA_ARGS__); \ 304 } \ 305 } while (0) 306 307 // Implementation detail: internal macro to create static category and add 308 // event if the category is enabled. 309 #define INTERNAL_TRACE_EVENT_ADD_WITH_TIMESTAMP(phase, category_group, name, \ 310 timestamp, flags, ...) \ 311 do { \ 312 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ 313 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \ 314 trace_event_internal::AddTraceEventWithThreadIdAndTimestamp( \ 315 phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ 316 trace_event_internal::kGlobalScope, trace_event_internal::kNoId, \ 317 TRACE_EVENT_API_CURRENT_THREAD_ID, timestamp, \ 318 flags | TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP, \ 319 trace_event_internal::kNoId, ##__VA_ARGS__); \ 320 } \ 321 } while (0) 322 323 // Implementation detail: internal macro to create static category and add 324 // event if the category is enabled. 325 #define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \ 326 phase, category_group, name, id, thread_id, timestamp, flags, ...) \ 327 do { \ 328 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ 329 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \ 330 trace_event_internal::TraceID trace_event_trace_id((id)); \ 331 unsigned int trace_event_flags = \ 332 flags | trace_event_trace_id.id_flags(); \ 333 trace_event_internal::AddTraceEventWithThreadIdAndTimestamp( \ 334 phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ 335 trace_event_trace_id.scope(), trace_event_trace_id.raw_id(), \ 336 thread_id, timestamp, \ 337 trace_event_flags | TRACE_EVENT_FLAG_EXPLICIT_TIMESTAMP, \ 338 trace_event_internal::kNoId, ##__VA_ARGS__); \ 339 } \ 340 } while (0) 341 342 // The linked ID will not be mangled. 343 #define INTERNAL_TRACE_EVENT_ADD_LINK_IDS(category_group, name, id1, id2) \ 344 do { \ 345 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ 346 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \ 347 trace_event_internal::TraceID source_id((id1)); \ 348 unsigned int source_flags = source_id.id_flags(); \ 349 trace_event_internal::TraceID target_id((id2)); \ 350 trace_event_internal::AddTraceEvent( \ 351 TRACE_EVENT_PHASE_LINK_IDS, \ 352 INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ 353 source_id.scope(), source_id.raw_id(), source_flags, \ 354 trace_event_internal::kNoId, "linked_id", \ 355 target_id.AsConvertableToTraceFormat()); \ 356 } \ 357 } while (0) 358 359 // Implementation detail: internal macro to create static category and add 360 // metadata event if the category is enabled. 361 #define INTERNAL_TRACE_EVENT_METADATA_ADD(category_group, name, ...) \ 362 do { \ 363 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \ 364 if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED()) { \ 365 TRACE_EVENT_API_ADD_METADATA_EVENT( \ 366 INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \ 367 ##__VA_ARGS__); \ 368 } \ 369 } while (0) 370 371 // Implementation detail: internal macro to enter and leave a 372 // context based on the current scope. 373 #define INTERNAL_TRACE_EVENT_SCOPED_CONTEXT(category_group, name, context) \ 374 struct INTERNAL_TRACE_EVENT_UID(ScopedContext) { \ 375 public: \ 376 INTERNAL_TRACE_EVENT_UID(ScopedContext)(uint64_t cid) : cid_(cid) { \ 377 TRACE_EVENT_ENTER_CONTEXT(category_group, name, cid_); \ 378 } \ 379 ~INTERNAL_TRACE_EVENT_UID(ScopedContext)() { \ 380 TRACE_EVENT_LEAVE_CONTEXT(category_group, name, cid_); \ 381 } \ 382 \ 383 private: \ 384 uint64_t cid_; \ 385 /* Local class friendly DISALLOW_COPY_AND_ASSIGN */ \ 386 INTERNAL_TRACE_EVENT_UID(ScopedContext) \ 387 (const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {}; \ 388 void operator=(const INTERNAL_TRACE_EVENT_UID(ScopedContext)&) {}; \ 389 }; \ 390 INTERNAL_TRACE_EVENT_UID(ScopedContext) \ 391 INTERNAL_TRACE_EVENT_UID(scoped_context)(context); 392 393 // Implementation detail: internal macro to trace a task execution with the 394 // location where it was posted from. 395 #define INTERNAL_TRACE_TASK_EXECUTION(run_function, task) \ 396 TRACE_EVENT2("toplevel", run_function, "src_file", \ 397 (task).posted_from.file_name(), "src_func", \ 398 (task).posted_from.function_name()); \ 399 TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION INTERNAL_TRACE_EVENT_UID( \ 400 task_event)((task).posted_from.file_name()); 401 402 namespace trace_event_internal { 403 404 // Specify these values when the corresponding argument of AddTraceEvent is not 405 // used. 406 const int kZeroNumArgs = 0; 407 const std::nullptr_t kGlobalScope = nullptr; 408 const unsigned long long kNoId = 0; 409 410 // TraceID encapsulates an ID that can either be an integer or pointer. Pointers 411 // are by default mangled with the Process ID so that they are unlikely to 412 // collide when the same pointer is used on different processes. 413 class BASE_EXPORT TraceID { 414 public: 415 // Can be combined with WithScope. 416 class LocalId { 417 public: 418 explicit LocalId(unsigned long long raw_id) : raw_id_(raw_id) {} 419 unsigned long long raw_id() const { return raw_id_; } 420 private: 421 unsigned long long raw_id_; 422 }; 423 424 // Can be combined with WithScope. 425 class GlobalId { 426 public: 427 explicit GlobalId(unsigned long long raw_id) : raw_id_(raw_id) {} 428 unsigned long long raw_id() const { return raw_id_; } 429 private: 430 unsigned long long raw_id_; 431 }; 432 433 class WithScope { 434 public: 435 WithScope(const char* scope, unsigned long long raw_id) 436 : scope_(scope), raw_id_(raw_id) {} 437 WithScope(const char* scope, LocalId local_id) 438 : scope_(scope), raw_id_(local_id.raw_id()) { 439 id_flags_ = TRACE_EVENT_FLAG_HAS_LOCAL_ID; 440 } 441 WithScope(const char* scope, GlobalId global_id) 442 : scope_(scope), raw_id_(global_id.raw_id()) { 443 id_flags_ = TRACE_EVENT_FLAG_HAS_GLOBAL_ID; 444 } 445 WithScope(const char* scope, 446 unsigned long long prefix, 447 unsigned long long raw_id) 448 : scope_(scope), has_prefix_(true), prefix_(prefix), raw_id_(raw_id) {} 449 WithScope(const char* scope, unsigned long long prefix, GlobalId global_id) 450 : scope_(scope), 451 has_prefix_(true), 452 prefix_(prefix), 453 raw_id_(global_id.raw_id()) { 454 id_flags_ = TRACE_EVENT_FLAG_HAS_GLOBAL_ID; 455 } 456 unsigned long long raw_id() const { return raw_id_; } 457 const char* scope() const { return scope_; } 458 bool has_prefix() const { return has_prefix_; } 459 unsigned long long prefix() const { return prefix_; } 460 unsigned int id_flags() const { return id_flags_; } 461 462 private: 463 const char* scope_ = nullptr; 464 bool has_prefix_ = false; 465 unsigned long long prefix_; 466 unsigned long long raw_id_; 467 unsigned int id_flags_ = TRACE_EVENT_FLAG_HAS_ID; 468 }; 469 470 // DEPRECATED: consider using LocalId or GlobalId, instead. 471 class DontMangle { 472 public: 473 explicit DontMangle(const void* raw_id) 474 : raw_id_(static_cast<unsigned long long>( 475 reinterpret_cast<uintptr_t>(raw_id))) {} 476 explicit DontMangle(unsigned long long raw_id) : raw_id_(raw_id) {} 477 explicit DontMangle(unsigned long raw_id) : raw_id_(raw_id) {} 478 explicit DontMangle(unsigned int raw_id) : raw_id_(raw_id) {} 479 explicit DontMangle(unsigned short raw_id) : raw_id_(raw_id) {} 480 explicit DontMangle(unsigned char raw_id) : raw_id_(raw_id) {} 481 explicit DontMangle(long long raw_id) 482 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 483 explicit DontMangle(long raw_id) 484 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 485 explicit DontMangle(int raw_id) 486 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 487 explicit DontMangle(short raw_id) 488 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 489 explicit DontMangle(signed char raw_id) 490 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 491 unsigned long long raw_id() const { return raw_id_; } 492 private: 493 unsigned long long raw_id_; 494 }; 495 496 // DEPRECATED: consider using LocalId or GlobalId, instead. 497 class ForceMangle { 498 public: 499 explicit ForceMangle(unsigned long long raw_id) : raw_id_(raw_id) {} 500 explicit ForceMangle(unsigned long raw_id) : raw_id_(raw_id) {} 501 explicit ForceMangle(unsigned int raw_id) : raw_id_(raw_id) {} 502 explicit ForceMangle(unsigned short raw_id) : raw_id_(raw_id) {} 503 explicit ForceMangle(unsigned char raw_id) : raw_id_(raw_id) {} 504 explicit ForceMangle(long long raw_id) 505 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 506 explicit ForceMangle(long raw_id) 507 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 508 explicit ForceMangle(int raw_id) 509 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 510 explicit ForceMangle(short raw_id) 511 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 512 explicit ForceMangle(signed char raw_id) 513 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 514 unsigned long long raw_id() const { return raw_id_; } 515 private: 516 unsigned long long raw_id_; 517 }; 518 519 TraceID(const void* raw_id) : raw_id_(static_cast<unsigned long long>( 520 reinterpret_cast<uintptr_t>(raw_id))) { 521 id_flags_ = TRACE_EVENT_FLAG_HAS_ID | TRACE_EVENT_FLAG_MANGLE_ID; 522 } 523 TraceID(ForceMangle raw_id) : raw_id_(raw_id.raw_id()) { 524 id_flags_ = TRACE_EVENT_FLAG_HAS_ID | TRACE_EVENT_FLAG_MANGLE_ID; 525 } 526 TraceID(DontMangle raw_id) : raw_id_(raw_id.raw_id()) {} 527 TraceID(unsigned long long raw_id) : raw_id_(raw_id) {} 528 TraceID(unsigned long raw_id) : raw_id_(raw_id) {} 529 TraceID(unsigned int raw_id) : raw_id_(raw_id) {} 530 TraceID(unsigned short raw_id) : raw_id_(raw_id) {} 531 TraceID(unsigned char raw_id) : raw_id_(raw_id) {} 532 TraceID(long long raw_id) 533 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 534 TraceID(long raw_id) 535 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 536 TraceID(int raw_id) 537 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 538 TraceID(short raw_id) 539 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 540 TraceID(signed char raw_id) 541 : raw_id_(static_cast<unsigned long long>(raw_id)) {} 542 TraceID(LocalId raw_id) : raw_id_(raw_id.raw_id()) { 543 id_flags_ = TRACE_EVENT_FLAG_HAS_LOCAL_ID; 544 } 545 TraceID(GlobalId raw_id) : raw_id_(raw_id.raw_id()) { 546 id_flags_ = TRACE_EVENT_FLAG_HAS_GLOBAL_ID; 547 } 548 TraceID(WithScope scoped_id) 549 : scope_(scoped_id.scope()), 550 has_prefix_(scoped_id.has_prefix()), 551 prefix_(scoped_id.prefix()), 552 raw_id_(scoped_id.raw_id()), 553 id_flags_(scoped_id.id_flags()) {} 554 555 unsigned long long raw_id() const { return raw_id_; } 556 const char* scope() const { return scope_; } 557 bool has_prefix() const { return has_prefix_; } 558 unsigned long long prefix() const { return prefix_; } 559 unsigned int id_flags() const { return id_flags_; } 560 561 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> 562 AsConvertableToTraceFormat() const; 563 564 private: 565 const char* scope_ = nullptr; 566 bool has_prefix_ = false; 567 unsigned long long prefix_; 568 unsigned long long raw_id_; 569 unsigned int id_flags_ = TRACE_EVENT_FLAG_HAS_ID; 570 }; 571 572 // Simple union to store various types as unsigned long long. 573 union TraceValueUnion { 574 bool as_bool; 575 unsigned long long as_uint; 576 long long as_int; 577 double as_double; 578 const void* as_pointer; 579 const char* as_string; 580 }; 581 582 // Simple container for const char* that should be copied instead of retained. 583 class TraceStringWithCopy { 584 public: 585 explicit TraceStringWithCopy(const char* str) : str_(str) {} 586 const char* str() const { return str_; } 587 private: 588 const char* str_; 589 }; 590 591 // Define SetTraceValue for each allowed type. It stores the type and 592 // value in the return arguments. This allows this API to avoid declaring any 593 // structures so that it is portable to third_party libraries. 594 #define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, \ 595 arg_expression, \ 596 union_member, \ 597 value_type_id) \ 598 static inline void SetTraceValue( \ 599 actual_type arg, \ 600 unsigned char* type, \ 601 unsigned long long* value) { \ 602 TraceValueUnion type_value; \ 603 type_value.union_member = arg_expression; \ 604 *type = value_type_id; \ 605 *value = type_value.as_uint; \ 606 } 607 // Simpler form for int types that can be safely casted. 608 #define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, \ 609 value_type_id) \ 610 static inline void SetTraceValue( \ 611 actual_type arg, \ 612 unsigned char* type, \ 613 unsigned long long* value) { \ 614 *type = value_type_id; \ 615 *value = static_cast<unsigned long long>(arg); \ 616 } 617 618 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT) 619 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long, TRACE_VALUE_TYPE_UINT) 620 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT) 621 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT) 622 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT) 623 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT) 624 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long, TRACE_VALUE_TYPE_INT) 625 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT) 626 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT) 627 INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT) 628 INTERNAL_DECLARE_SET_TRACE_VALUE(bool, arg, as_bool, TRACE_VALUE_TYPE_BOOL) 629 INTERNAL_DECLARE_SET_TRACE_VALUE(double, arg, as_double, 630 TRACE_VALUE_TYPE_DOUBLE) 631 INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, arg, as_pointer, 632 TRACE_VALUE_TYPE_POINTER) 633 INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, arg, as_string, 634 TRACE_VALUE_TYPE_STRING) 635 INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, arg.str(), 636 as_string, TRACE_VALUE_TYPE_COPY_STRING) 637 638 #undef INTERNAL_DECLARE_SET_TRACE_VALUE 639 #undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT 640 641 // std::string version of SetTraceValue so that trace arguments can be strings. 642 static inline void SetTraceValue(const std::string& arg, 643 unsigned char* type, 644 unsigned long long* value) { 645 TraceValueUnion type_value; 646 type_value.as_string = arg.c_str(); 647 *type = TRACE_VALUE_TYPE_COPY_STRING; 648 *value = type_value.as_uint; 649 } 650 651 // base::Time, base::TimeTicks, etc. versions of SetTraceValue to make it easier 652 // to trace these types. 653 static inline void SetTraceValue(const base::Time arg, 654 unsigned char* type, 655 unsigned long long* value) { 656 *type = TRACE_VALUE_TYPE_INT; 657 *value = arg.ToInternalValue(); 658 } 659 660 static inline void SetTraceValue(const base::TimeTicks arg, 661 unsigned char* type, 662 unsigned long long* value) { 663 *type = TRACE_VALUE_TYPE_INT; 664 *value = arg.ToInternalValue(); 665 } 666 667 static inline void SetTraceValue(const base::ThreadTicks arg, 668 unsigned char* type, 669 unsigned long long* value) { 670 *type = TRACE_VALUE_TYPE_INT; 671 *value = arg.ToInternalValue(); 672 } 673 674 // These AddTraceEvent and AddTraceEventWithThreadIdAndTimestamp template 675 // functions are defined here instead of in the macro, because the arg_values 676 // could be temporary objects, such as std::string. In order to store 677 // pointers to the internal c_str and pass through to the tracing API, 678 // the arg_values must live throughout these procedures. 679 680 template <class ARG1_CONVERTABLE_TYPE> 681 static inline base::trace_event::TraceEventHandle 682 AddTraceEventWithThreadIdAndTimestamp( 683 char phase, 684 const unsigned char* category_group_enabled, 685 const char* name, 686 const char* scope, 687 unsigned long long id, 688 int thread_id, 689 const base::TimeTicks& timestamp, 690 unsigned int flags, 691 unsigned long long bind_id, 692 const char* arg1_name, 693 std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val) { 694 const int num_args = 1; 695 unsigned char arg_types[1] = { TRACE_VALUE_TYPE_CONVERTABLE }; 696 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> 697 convertable_values[1] = {std::move(arg1_val)}; 698 return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( 699 phase, category_group_enabled, name, scope, id, bind_id, thread_id, 700 timestamp, num_args, &arg1_name, arg_types, NULL, convertable_values, 701 flags); 702 } 703 704 template <class ARG1_TYPE, class ARG2_CONVERTABLE_TYPE> 705 static inline base::trace_event::TraceEventHandle 706 AddTraceEventWithThreadIdAndTimestamp( 707 char phase, 708 const unsigned char* category_group_enabled, 709 const char* name, 710 const char* scope, 711 unsigned long long id, 712 int thread_id, 713 const base::TimeTicks& timestamp, 714 unsigned int flags, 715 unsigned long long bind_id, 716 const char* arg1_name, 717 const ARG1_TYPE& arg1_val, 718 const char* arg2_name, 719 std::unique_ptr<ARG2_CONVERTABLE_TYPE> arg2_val) { 720 const int num_args = 2; 721 const char* arg_names[2] = { arg1_name, arg2_name }; 722 723 unsigned char arg_types[2]; 724 unsigned long long arg_values[2]; 725 SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]); 726 arg_types[1] = TRACE_VALUE_TYPE_CONVERTABLE; 727 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> 728 convertable_values[2] = {nullptr, std::move(arg2_val)}; 729 return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( 730 phase, category_group_enabled, name, scope, id, bind_id, thread_id, 731 timestamp, num_args, arg_names, arg_types, arg_values, convertable_values, 732 flags); 733 } 734 735 template <class ARG1_CONVERTABLE_TYPE, class ARG2_TYPE> 736 static inline base::trace_event::TraceEventHandle 737 AddTraceEventWithThreadIdAndTimestamp( 738 char phase, 739 const unsigned char* category_group_enabled, 740 const char* name, 741 const char* scope, 742 unsigned long long id, 743 int thread_id, 744 const base::TimeTicks& timestamp, 745 unsigned int flags, 746 unsigned long long bind_id, 747 const char* arg1_name, 748 std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val, 749 const char* arg2_name, 750 const ARG2_TYPE& arg2_val) { 751 const int num_args = 2; 752 const char* arg_names[2] = { arg1_name, arg2_name }; 753 754 unsigned char arg_types[2]; 755 unsigned long long arg_values[2]; 756 arg_types[0] = TRACE_VALUE_TYPE_CONVERTABLE; 757 arg_values[0] = 0; 758 SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]); 759 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> 760 convertable_values[2] = {std::move(arg1_val), nullptr}; 761 return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( 762 phase, category_group_enabled, name, scope, id, bind_id, thread_id, 763 timestamp, num_args, arg_names, arg_types, arg_values, convertable_values, 764 flags); 765 } 766 767 template <class ARG1_CONVERTABLE_TYPE, class ARG2_CONVERTABLE_TYPE> 768 static inline base::trace_event::TraceEventHandle 769 AddTraceEventWithThreadIdAndTimestamp( 770 char phase, 771 const unsigned char* category_group_enabled, 772 const char* name, 773 const char* scope, 774 unsigned long long id, 775 int thread_id, 776 const base::TimeTicks& timestamp, 777 unsigned int flags, 778 unsigned long long bind_id, 779 const char* arg1_name, 780 std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val, 781 const char* arg2_name, 782 std::unique_ptr<ARG2_CONVERTABLE_TYPE> arg2_val) { 783 const int num_args = 2; 784 const char* arg_names[2] = { arg1_name, arg2_name }; 785 unsigned char arg_types[2] = 786 { TRACE_VALUE_TYPE_CONVERTABLE, TRACE_VALUE_TYPE_CONVERTABLE }; 787 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> 788 convertable_values[2] = {std::move(arg1_val), std::move(arg2_val)}; 789 return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( 790 phase, category_group_enabled, name, scope, id, bind_id, thread_id, 791 timestamp, num_args, arg_names, arg_types, NULL, convertable_values, 792 flags); 793 } 794 795 static inline base::trace_event::TraceEventHandle 796 AddTraceEventWithThreadIdAndTimestamp( 797 char phase, 798 const unsigned char* category_group_enabled, 799 const char* name, 800 const char* scope, 801 unsigned long long id, 802 int thread_id, 803 const base::TimeTicks& timestamp, 804 unsigned int flags, 805 unsigned long long bind_id) { 806 return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( 807 phase, category_group_enabled, name, scope, id, bind_id, thread_id, 808 timestamp, kZeroNumArgs, NULL, NULL, NULL, NULL, flags); 809 } 810 811 static inline base::trace_event::TraceEventHandle AddTraceEvent( 812 char phase, 813 const unsigned char* category_group_enabled, 814 const char* name, 815 const char* scope, 816 unsigned long long id, 817 unsigned int flags, 818 unsigned long long bind_id) { 819 const int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); 820 const base::TimeTicks now = base::TimeTicks::Now(); 821 return AddTraceEventWithThreadIdAndTimestamp( 822 phase, category_group_enabled, name, scope, id, thread_id, now, flags, 823 bind_id); 824 } 825 826 template<class ARG1_TYPE> 827 static inline base::trace_event::TraceEventHandle 828 AddTraceEventWithThreadIdAndTimestamp( 829 char phase, 830 const unsigned char* category_group_enabled, 831 const char* name, 832 const char* scope, 833 unsigned long long id, 834 int thread_id, 835 const base::TimeTicks& timestamp, 836 unsigned int flags, 837 unsigned long long bind_id, 838 const char* arg1_name, 839 const ARG1_TYPE& arg1_val) { 840 const int num_args = 1; 841 unsigned char arg_types[1]; 842 unsigned long long arg_values[1]; 843 SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]); 844 return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( 845 phase, category_group_enabled, name, scope, id, bind_id, thread_id, 846 timestamp, num_args, &arg1_name, arg_types, arg_values, NULL, flags); 847 } 848 849 template<class ARG1_TYPE> 850 static inline base::trace_event::TraceEventHandle AddTraceEvent( 851 char phase, 852 const unsigned char* category_group_enabled, 853 const char* name, 854 const char* scope, 855 unsigned long long id, 856 unsigned int flags, 857 unsigned long long bind_id, 858 const char* arg1_name, 859 const ARG1_TYPE& arg1_val) { 860 int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); 861 base::TimeTicks now = base::TimeTicks::Now(); 862 return AddTraceEventWithThreadIdAndTimestamp( 863 phase, category_group_enabled, name, scope, id, thread_id, now, flags, 864 bind_id, arg1_name, arg1_val); 865 } 866 867 template <class ARG1_CONVERTABLE_TYPE> 868 static inline base::trace_event::TraceEventHandle AddTraceEvent( 869 char phase, 870 const unsigned char* category_group_enabled, 871 const char* name, 872 const char* scope, 873 unsigned long long id, 874 unsigned int flags, 875 unsigned long long bind_id, 876 const char* arg1_name, 877 std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val) { 878 int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); 879 base::TimeTicks now = base::TimeTicks::Now(); 880 return AddTraceEventWithThreadIdAndTimestamp( 881 phase, category_group_enabled, name, scope, id, thread_id, now, flags, 882 bind_id, arg1_name, std::move(arg1_val)); 883 } 884 885 template<class ARG1_TYPE, class ARG2_TYPE> 886 static inline base::trace_event::TraceEventHandle 887 AddTraceEventWithThreadIdAndTimestamp( 888 char phase, 889 const unsigned char* category_group_enabled, 890 const char* name, 891 const char* scope, 892 unsigned long long id, 893 int thread_id, 894 const base::TimeTicks& timestamp, 895 unsigned int flags, 896 unsigned long long bind_id, 897 const char* arg1_name, 898 const ARG1_TYPE& arg1_val, 899 const char* arg2_name, 900 const ARG2_TYPE& arg2_val) { 901 const int num_args = 2; 902 const char* arg_names[2] = { arg1_name, arg2_name }; 903 unsigned char arg_types[2]; 904 unsigned long long arg_values[2]; 905 SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]); 906 SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]); 907 return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( 908 phase, category_group_enabled, name, scope, id, bind_id, thread_id, 909 timestamp, num_args, arg_names, arg_types, arg_values, NULL, flags); 910 } 911 912 template <class ARG1_CONVERTABLE_TYPE, class ARG2_TYPE> 913 static inline base::trace_event::TraceEventHandle AddTraceEvent( 914 char phase, 915 const unsigned char* category_group_enabled, 916 const char* name, 917 const char* scope, 918 unsigned long long id, 919 unsigned int flags, 920 unsigned long long bind_id, 921 const char* arg1_name, 922 std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val, 923 const char* arg2_name, 924 const ARG2_TYPE& arg2_val) { 925 int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); 926 base::TimeTicks now = base::TimeTicks::Now(); 927 return AddTraceEventWithThreadIdAndTimestamp( 928 phase, category_group_enabled, name, scope, id, thread_id, now, flags, 929 bind_id, arg1_name, std::move(arg1_val), arg2_name, arg2_val); 930 } 931 932 template <class ARG1_TYPE, class ARG2_CONVERTABLE_TYPE> 933 static inline base::trace_event::TraceEventHandle AddTraceEvent( 934 char phase, 935 const unsigned char* category_group_enabled, 936 const char* name, 937 const char* scope, 938 unsigned long long id, 939 unsigned int flags, 940 unsigned long long bind_id, 941 const char* arg1_name, 942 const ARG1_TYPE& arg1_val, 943 const char* arg2_name, 944 std::unique_ptr<ARG2_CONVERTABLE_TYPE> arg2_val) { 945 int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); 946 base::TimeTicks now = base::TimeTicks::Now(); 947 return AddTraceEventWithThreadIdAndTimestamp( 948 phase, category_group_enabled, name, scope, id, thread_id, now, flags, 949 bind_id, arg1_name, arg1_val, arg2_name, std::move(arg2_val)); 950 } 951 952 template <class ARG1_CONVERTABLE_TYPE, class ARG2_CONVERTABLE_TYPE> 953 static inline base::trace_event::TraceEventHandle AddTraceEvent( 954 char phase, 955 const unsigned char* category_group_enabled, 956 const char* name, 957 const char* scope, 958 unsigned long long id, 959 unsigned int flags, 960 unsigned long long bind_id, 961 const char* arg1_name, 962 std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val, 963 const char* arg2_name, 964 std::unique_ptr<ARG2_CONVERTABLE_TYPE> arg2_val) { 965 int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); 966 base::TimeTicks now = base::TimeTicks::Now(); 967 return AddTraceEventWithThreadIdAndTimestamp( 968 phase, category_group_enabled, name, scope, id, thread_id, now, flags, 969 bind_id, arg1_name, std::move(arg1_val), arg2_name, std::move(arg2_val)); 970 } 971 972 template<class ARG1_TYPE, class ARG2_TYPE> 973 static inline base::trace_event::TraceEventHandle AddTraceEvent( 974 char phase, 975 const unsigned char* category_group_enabled, 976 const char* name, 977 const char* scope, 978 unsigned long long id, 979 unsigned int flags, 980 unsigned long long bind_id, 981 const char* arg1_name, 982 const ARG1_TYPE& arg1_val, 983 const char* arg2_name, 984 const ARG2_TYPE& arg2_val) { 985 int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); 986 base::TimeTicks now = base::TimeTicks::Now(); 987 return AddTraceEventWithThreadIdAndTimestamp( 988 phase, category_group_enabled, name, scope, id, thread_id, now, flags, 989 bind_id, arg1_name, arg1_val, arg2_name, arg2_val); 990 } 991 992 template <class ARG1_CONVERTABLE_TYPE> 993 static inline void AddMetadataEvent( 994 const unsigned char* category_group_enabled, 995 const char* event_name, 996 const char* arg_name, 997 std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg_value) { 998 const char* arg_names[1] = {arg_name}; 999 unsigned char arg_types[1] = {TRACE_VALUE_TYPE_CONVERTABLE}; 1000 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> 1001 convertable_values[1] = {std::move(arg_value)}; 1002 base::trace_event::TraceLog::GetInstance()->AddMetadataEvent( 1003 category_group_enabled, event_name, 1004 1, // num_args 1005 arg_names, arg_types, 1006 nullptr, // arg_values 1007 convertable_values, TRACE_EVENT_FLAG_NONE); 1008 } 1009 1010 template <class ARG1_TYPE> 1011 static void AddMetadataEvent(const unsigned char* category_group_enabled, 1012 const char* event_name, 1013 const char* arg_name, 1014 const ARG1_TYPE& arg_val) { 1015 const int num_args = 1; 1016 const char* arg_names[1] = {arg_name}; 1017 unsigned char arg_types[1]; 1018 unsigned long long arg_values[1]; 1019 SetTraceValue(arg_val, &arg_types[0], &arg_values[0]); 1020 1021 base::trace_event::TraceLog::GetInstance()->AddMetadataEvent( 1022 category_group_enabled, event_name, num_args, arg_names, arg_types, 1023 arg_values, nullptr, TRACE_EVENT_FLAG_NONE); 1024 } 1025 1026 // Used by TRACE_EVENTx macros. Do not use directly. 1027 class TRACE_EVENT_API_CLASS_EXPORT ScopedTracer { 1028 public: 1029 // Note: members of data_ intentionally left uninitialized. See Initialize. 1030 ScopedTracer() : p_data_(NULL) {} 1031 1032 ~ScopedTracer() { 1033 if (p_data_ && *data_.category_group_enabled) { 1034 TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION( 1035 data_.category_group_enabled, data_.name, data_.event_handle); 1036 } 1037 } 1038 1039 void Initialize(const unsigned char* category_group_enabled, 1040 const char* name, 1041 base::trace_event::TraceEventHandle event_handle) { 1042 data_.category_group_enabled = category_group_enabled; 1043 data_.name = name; 1044 data_.event_handle = event_handle; 1045 p_data_ = &data_; 1046 } 1047 1048 private: 1049 // This Data struct workaround is to avoid initializing all the members 1050 // in Data during construction of this object, since this object is always 1051 // constructed, even when tracing is disabled. If the members of Data were 1052 // members of this class instead, compiler warnings occur about potential 1053 // uninitialized accesses. 1054 struct Data { 1055 const unsigned char* category_group_enabled; 1056 const char* name; 1057 base::trace_event::TraceEventHandle event_handle; 1058 }; 1059 Data* p_data_; 1060 Data data_; 1061 }; 1062 1063 // Used by TRACE_EVENT_BINARY_EFFICIENTx macro. Do not use directly. 1064 class TRACE_EVENT_API_CLASS_EXPORT ScopedTraceBinaryEfficient { 1065 public: 1066 ScopedTraceBinaryEfficient(const char* category_group, const char* name); 1067 ~ScopedTraceBinaryEfficient(); 1068 1069 private: 1070 const unsigned char* category_group_enabled_; 1071 const char* name_; 1072 base::trace_event::TraceEventHandle event_handle_; 1073 }; 1074 1075 // This macro generates less code then TRACE_EVENT0 but is also 1076 // slower to execute when tracing is off. It should generally only be 1077 // used with code that is seldom executed or conditionally executed 1078 // when debugging. 1079 // For now the category_group must be "gpu". 1080 #define TRACE_EVENT_BINARY_EFFICIENT0(category_group, name) \ 1081 trace_event_internal::ScopedTraceBinaryEfficient \ 1082 INTERNAL_TRACE_EVENT_UID(scoped_trace)(category_group, name); 1083 1084 } // namespace trace_event_internal 1085 1086 namespace base { 1087 namespace trace_event { 1088 1089 template<typename IDType> class TraceScopedTrackableObject { 1090 public: 1091 TraceScopedTrackableObject(const char* category_group, const char* name, 1092 IDType id) 1093 : category_group_(category_group), 1094 name_(name), 1095 id_(id) { 1096 TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group_, name_, id_); 1097 } 1098 1099 template <typename ArgType> void snapshot(ArgType snapshot) { 1100 TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group_, name_, id_, snapshot); 1101 } 1102 1103 ~TraceScopedTrackableObject() { 1104 TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group_, name_, id_); 1105 } 1106 1107 private: 1108 const char* category_group_; 1109 const char* name_; 1110 IDType id_; 1111 1112 DISALLOW_COPY_AND_ASSIGN(TraceScopedTrackableObject); 1113 }; 1114 1115 } // namespace trace_event 1116 } // namespace base 1117 1118 #endif // BASE_TRACE_EVENT_TRACE_EVENT_H_ 1119