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