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 402namespace trace_event_internal { 403 404// Specify these values when the corresponding argument of AddTraceEvent is not 405// used. 406const int kZeroNumArgs = 0; 407const std::nullptr_t kGlobalScope = nullptr; 408const 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. 413class 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. 573union 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. 583class 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 618INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT) 619INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long, TRACE_VALUE_TYPE_UINT) 620INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT) 621INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT) 622INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT) 623INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT) 624INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long, TRACE_VALUE_TYPE_INT) 625INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT) 626INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT) 627INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT) 628INTERNAL_DECLARE_SET_TRACE_VALUE(bool, arg, as_bool, TRACE_VALUE_TYPE_BOOL) 629INTERNAL_DECLARE_SET_TRACE_VALUE(double, arg, as_double, 630 TRACE_VALUE_TYPE_DOUBLE) 631INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, arg, as_pointer, 632 TRACE_VALUE_TYPE_POINTER) 633INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, arg, as_string, 634 TRACE_VALUE_TYPE_STRING) 635INTERNAL_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. 642static 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. 653static 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 660static 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 667static 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 680template <class ARG1_CONVERTABLE_TYPE> 681static inline base::trace_event::TraceEventHandle 682AddTraceEventWithThreadIdAndTimestamp( 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 704template <class ARG1_TYPE, class ARG2_CONVERTABLE_TYPE> 705static inline base::trace_event::TraceEventHandle 706AddTraceEventWithThreadIdAndTimestamp( 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 735template <class ARG1_CONVERTABLE_TYPE, class ARG2_TYPE> 736static inline base::trace_event::TraceEventHandle 737AddTraceEventWithThreadIdAndTimestamp( 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 767template <class ARG1_CONVERTABLE_TYPE, class ARG2_CONVERTABLE_TYPE> 768static inline base::trace_event::TraceEventHandle 769AddTraceEventWithThreadIdAndTimestamp( 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 795static inline base::trace_event::TraceEventHandle 796AddTraceEventWithThreadIdAndTimestamp( 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 811static 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 826template<class ARG1_TYPE> 827static inline base::trace_event::TraceEventHandle 828AddTraceEventWithThreadIdAndTimestamp( 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 849template<class ARG1_TYPE> 850static 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 867template <class ARG1_CONVERTABLE_TYPE> 868static 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 885template<class ARG1_TYPE, class ARG2_TYPE> 886static inline base::trace_event::TraceEventHandle 887AddTraceEventWithThreadIdAndTimestamp( 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 912template <class ARG1_CONVERTABLE_TYPE, class ARG2_TYPE> 913static 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 932template <class ARG1_TYPE, class ARG2_CONVERTABLE_TYPE> 933static 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 952template <class ARG1_CONVERTABLE_TYPE, class ARG2_CONVERTABLE_TYPE> 953static 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 972template<class ARG1_TYPE, class ARG2_TYPE> 973static 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 992template <class ARG1_CONVERTABLE_TYPE> 993static 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 1010template <class ARG1_TYPE> 1011static 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. 1027class 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. 1064class 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 1086namespace base { 1087namespace trace_event { 1088 1089template<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