13cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Copyright (c) 2013 The Chromium Authors. All rights reserved. 23cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Use of this source code is governed by a BSD-style license that can be 33cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// found in the LICENSE file. 43cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 53cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Trace events are for tracking application performance and resource usage. 63cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Macros are provided to track: 73cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Begin and end of function calls 83cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Counters 93cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 103cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Events are issued against categories. Whereas LOG's 113cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// categories are statically defined, TRACE categories are created 123cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// implicitly with a string. For example: 133cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent") 143cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 153cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Events can be INSTANT, or can be pairs of BEGIN and END in the same scope: 163cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly") 173cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// doSomethingCostly() 183cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly") 193cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Note: our tools can't always determine the correct BEGIN/END pairs unless 203cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// these are used in the same scope. Use ASYNC_BEGIN/ASYNC_END macros if you need them 213cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// to be in separate scopes. 223cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 233cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// A common use case is to trace entire function scopes. This 243cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// issues a trace BEGIN and END automatically: 253cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// void doSomethingCostly() { 263cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly"); 273cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// ... 283cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// } 293cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 303cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Additional parameters can be associated with an event: 313cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// void doSomethingCostly2(int howMuch) { 323cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly", 333cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// "howMuch", howMuch); 343cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// ... 353cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// } 363cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 373cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// The trace system will automatically add to this information the 383cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// current process id, thread id, and a timestamp in microseconds. 393cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 403cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// To trace an asynchronous procedure such as an IPC send/receive, use ASYNC_BEGIN and 413cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// ASYNC_END: 423cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// [single threaded sender code] 433cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// static int send_count = 0; 443cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// ++send_count; 453cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count); 463cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Send(new MyMessage(send_count)); 473cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// [receive code] 483cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// void OnMyMessage(send_count) { 493cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT_ASYNC_END0("ipc", "message", send_count); 503cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// } 513cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs. 523cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process. Pointers can 533cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// be used for the ID parameter, and they will be mangled internally so that 543cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// the same pointer on two different processes will not match. For example: 553cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// class MyTracedClass { 563cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// public: 573cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// MyTracedClass() { 583cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this); 593cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// } 603cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// ~MyTracedClass() { 613cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this); 623cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// } 633cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// } 643cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 653cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Trace event also supports counters, which is a way to track a quantity 663cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// as it varies over time. Counters are created with the following macro: 673cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue); 683cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 693cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Counters are process-specific. The macro itself can be issued from any 703cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// thread, however. 713cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 723cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Sometimes, you want to track two counters at once. You can do this with two 733cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// counter macros: 743cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter0", g_myCounterValue[0]); 753cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter1", g_myCounterValue[1]); 763cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Or you can do it with a combined macro: 773cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_COUNTER2("MY_SUBSYSTEM", "myCounter", 783cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// "bytesPinned", g_myCounterValue[0], 793cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// "bytesAllocated", g_myCounterValue[1]); 803cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// This indicates to the tracing UI that these counters should be displayed 813cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// in a single graph, as a summed area chart. 823cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 833cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Since counters are in a global namespace, you may want to disembiguate with a 843cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// unique ID, by using the TRACE_COUNTER_ID* variations. 853cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 863cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// By default, trace collection is compiled in, but turned off at runtime. 873cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Collecting trace data is the responsibility of the embedding 883cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// application. In Chrome's case, navigating to about:tracing will turn on 893cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// tracing and display data collected across all active processes. 903cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 913cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 923cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Memory scoping note: 933cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Tracing copies the pointers, not the string content, of the strings passed 943cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// in for category, name, and arg_names. Thus, the following code will 953cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// cause problems: 963cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// char* str = strdup("impprtantName"); 973cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT_INSTANT0("SUBSYSTEM", str); // BAD! 983cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// free(str); // Trace system now has dangling pointer 993cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 1003cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// To avoid this issue with the |name| and |arg_name| parameters, use the 1013cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT_COPY_XXX overloads of the macros at additional runtime overhead. 1023cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Notes: The category must always be in a long-lived char* (i.e. static const). 1033cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// The |arg_values|, when used, are always deep copied with the _COPY 1043cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// macros. 1053cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 1063cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// When are string argument values copied: 1073cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// const char* arg_values are only referenced by default: 1083cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT1("category", "name", 1093cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// "arg1", "literal string is only referenced"); 1103cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Use TRACE_STR_COPY to force copying of a const char*: 1113cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT1("category", "name", 1123cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// "arg1", TRACE_STR_COPY("string will be copied")); 1133cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// std::string arg_values are always copied: 1143cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT1("category", "name", 1153cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// "arg1", std::string("string will be copied")); 1163cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 1173cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 1183cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Thread Safety: 1193cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// A thread safe singleton and mutex are used for thread safety. Category 1203cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// enabled flags are used to limit the performance impact when the system 1213cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// is not enabled. 1223cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 1233cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT macros first cache a pointer to a category. The categories are 1243cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// statically allocated and safe at all times, even after exit. Fetching a 1253cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// category is protected by the TraceLog::lock_. Multiple threads initializing 1263cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// the static variable is safe, as they will be serialized by the lock and 1273cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// multiple calls will return the same pointer to the category. 1283cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 1293cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Then the category_enabled flag is checked. This is a unsigned char, and 1303cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// not intended to be multithread safe. It optimizes access to addTraceEvent 1313cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// which is threadsafe internally via TraceLog::lock_. The enabled flag may 1323cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// cause some threads to incorrectly call or skip calling addTraceEvent near 1333cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// the time of the system being enabled or disabled. This is acceptable as 1343cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// we tolerate some data loss while the system is being enabled/disabled and 1353cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// because addTraceEvent is threadsafe internally and checks the enabled state 1363cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// again under lock. 1373cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 1383cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Without the use of these static category pointers and enabled flags all 1393cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// trace points would carry a significant performance cost of aquiring a lock 1403cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// and resolving the category. 1413cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 1423cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#ifndef COMMON_TRACE_EVENT_H_ 1433cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define COMMON_TRACE_EVENT_H_ 1443cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 1453cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#include <string> 1463cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 1473cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#include "common/event_tracer.h" 1483cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 1493cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// By default, const char* argument values are assumed to have long-lived scope 1503cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// and will not be copied. Use this macro to force a const char* to be copied. 1513cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_STR_COPY(str) \ 1523cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick WebCore::TraceEvent::TraceStringWithCopy(str) 1533cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 1543cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Records a pair of begin and end events called "name" for the current 1553cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// scope, with 0, 1 or 2 associated arguments. If the category is not 1563cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// enabled, then this does nothing. 1573cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// - category and name strings must have application lifetime (statics or 1583cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// literals). They may not include " chars. 1593cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT0(category, name) \ 1603cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name) 1613cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT1(category, name, arg1_name, arg1_val) \ 1623cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val) 1633cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ 1643cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val, \ 1653cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) 1663cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 1673cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Records a single event called "name" immediately, with 0, 1 or 2 1683cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// associated arguments. If the category is not enabled, then this 1693cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// does nothing. 1703cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// - category and name strings must have application lifetime (statics or 1713cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// literals). They may not include " chars. 1723cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_INSTANT0(category, name) \ 1733cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ 1743cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_NONE) 1753cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \ 1763cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ 1773cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) 1783cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \ 1793cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) \ 1803cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ 1813cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ 1823cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) 1833cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_INSTANT0(category, name) \ 1843cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ 1853cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_COPY) 1863cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val) \ 1873cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ 1883cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) 1893cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, \ 1903cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) \ 1913cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \ 1923cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ 1933cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) 1943cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 1953cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Records a single BEGIN event called "name" immediately, with 0, 1 or 2 1963cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// associated arguments. If the category is not enabled, then this 1973cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// does nothing. 1983cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// - category and name strings must have application lifetime (statics or 1993cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// literals). They may not include " chars. 2003cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_BEGIN0(category, name) \ 2013cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ 2023cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_NONE) 2033cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) \ 2043cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ 2053cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) 2063cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \ 2073cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) \ 2083cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ 2093cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ 2103cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) 2113cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_BEGIN0(category, name) \ 2123cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ 2133cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_COPY) 2143cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) \ 2153cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ 2163cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) 2173cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \ 2183cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) \ 2193cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \ 2203cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ 2213cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) 2223cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 2233cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Records a single END event for "name" immediately. If the category 2243cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// is not enabled, then this does nothing. 2253cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// - category and name strings must have application lifetime (statics or 2263cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// literals). They may not include " chars. 2273cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_END0(category, name) \ 2283cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ 2293cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_NONE) 2303cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_END1(category, name, arg1_name, arg1_val) \ 2313cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ 2323cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) 2333cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \ 2343cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) \ 2353cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ 2363cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \ 2373cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) 2383cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_END0(category, name) \ 2393cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ 2403cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_COPY) 2413cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) \ 2423cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ 2433cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val) 2443cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \ 2453cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) \ 2463cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \ 2473cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \ 2483cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) 2493cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 2503cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Records the value of a counter called "name" immediately. Value 2513cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// must be representable as a 32 bit integer. 2523cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// - category and name strings must have application lifetime (statics or 2533cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// literals). They may not include " chars. 2543cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_COUNTER1(category, name, value) \ 2553cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ 2563cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_NONE, \ 2573cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick "value", static_cast<int>(value)) 2583cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_COPY_COUNTER1(category, name, value) \ 2593cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ 2603cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_COPY, \ 2613cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick "value", static_cast<int>(value)) 2623cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 2633cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Records the values of a multi-parted counter called "name" immediately. 2643cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// The UI will treat value1 and value2 as parts of a whole, displaying their 2653cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// values as a stacked-bar chart. 2663cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// - category and name strings must have application lifetime (statics or 2673cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// literals). They may not include " chars. 2683cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_COUNTER2(category, name, value1_name, value1_val, \ 2693cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick value2_name, value2_val) \ 2703cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ 2713cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_NONE, \ 2723cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick value1_name, static_cast<int>(value1_val), \ 2733cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick value2_name, static_cast<int>(value2_val)) 2743cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_COPY_COUNTER2(category, name, value1_name, value1_val, \ 2753cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick value2_name, value2_val) \ 2763cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \ 2773cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, TRACE_EVENT_FLAG_COPY, \ 2783cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick value1_name, static_cast<int>(value1_val), \ 2793cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick value2_name, static_cast<int>(value2_val)) 2803cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 2813cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Records the value of a counter called "name" immediately. Value 2823cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// must be representable as a 32 bit integer. 2833cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// - category and name strings must have application lifetime (statics or 2843cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// literals). They may not include " chars. 2853cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// - |id| is used to disambiguate counters with the same name. It must either 2863cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits 2873cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// will be xored with a hash of the process ID so that the same pointer on 2883cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// two different processes will not collide. 2893cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_COUNTER_ID1(category, name, id, value) \ 2903cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ 2913cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_NONE, \ 2923cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick "value", static_cast<int>(value)) 2933cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_COPY_COUNTER_ID1(category, name, id, value) \ 2943cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ 2953cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_COPY, \ 2963cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick "value", static_cast<int>(value)) 2973cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 2983cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Records the values of a multi-parted counter called "name" immediately. 2993cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// The UI will treat value1 and value2 as parts of a whole, displaying their 3003cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// values as a stacked-bar chart. 3013cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// - category and name strings must have application lifetime (statics or 3023cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// literals). They may not include " chars. 3033cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// - |id| is used to disambiguate counters with the same name. It must either 3043cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// be a pointer or an integer value up to 64 bits. If it's a pointer, the bits 3053cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// will be xored with a hash of the process ID so that the same pointer on 3063cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// two different processes will not collide. 3073cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_COUNTER_ID2(category, name, id, value1_name, value1_val, \ 3083cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick value2_name, value2_val) \ 3093cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ 3103cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_NONE, \ 3113cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick value1_name, static_cast<int>(value1_val), \ 3123cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick value2_name, static_cast<int>(value2_val)) 3133cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_COPY_COUNTER_ID2(category, name, id, value1_name, value1_val, \ 3143cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick value2_name, value2_val) \ 3153cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \ 3163cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_COPY, \ 3173cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick value1_name, static_cast<int>(value1_val), \ 3183cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick value2_name, static_cast<int>(value2_val)) 3193cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 3203cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2 3213cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// associated arguments. If the category is not enabled, then this 3223cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// does nothing. 3233cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// - category and name strings must have application lifetime (statics or 3243cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// literals). They may not include " chars. 3253cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// - |id| is used to match the ASYNC_BEGIN event with the ASYNC_END event. ASYNC 3263cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// events are considered to match if their category, name and id values all 3273cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// match. |id| must either be a pointer or an integer value up to 64 bits. If 3283cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// it's a pointer, the bits will be xored with a hash of the process ID so 3293cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// that the same pointer on two different processes will not collide. 3303cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// An asynchronous operation can consist of multiple phases. The first phase is 3313cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// defined by the ASYNC_BEGIN calls. Additional phases can be defined using the 3323cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// ASYNC_STEP_BEGIN macros. When the operation completes, call ASYNC_END. 3333cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// An async operation can span threads and processes, but all events in that 3343cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// operation must use the same |name| and |id|. Each event can have its own 3353cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// args. 3363cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_ASYNC_BEGIN0(category, name, id) \ 3373cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ 3383cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_NONE) 3393cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \ 3403cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ 3413cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) 3423cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \ 3433cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) \ 3443cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ 3453cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_NONE, \ 3463cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg1_name, arg1_val, arg2_name, arg2_val) 3473cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category, name, id) \ 3483cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ 3493cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_COPY) 3503cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category, name, id, arg1_name, arg1_val) \ 3513cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ 3523cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_COPY, \ 3533cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg1_name, arg1_val) 3543cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category, name, id, arg1_name, arg1_val, \ 3553cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) \ 3563cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \ 3573cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_COPY, \ 3583cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg1_name, arg1_val, arg2_name, arg2_val) 3593cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 3603cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Records a single ASYNC_STEP event for |step| immediately. If the category 3613cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// is not enabled, then this does nothing. The |name| and |id| must match the 3623cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// ASYNC_BEGIN event above. The |step| param identifies this step within the 3633cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// async event. This should be called at the beginning of the next phase of an 3643cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// asynchronous operation. 3653cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_ASYNC_STEP0(category, name, id, step) \ 3663cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ 3673cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_NONE, "step", step) 3683cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_ASYNC_STEP1(category, name, id, step, \ 3693cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg1_name, arg1_val) \ 3703cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ 3713cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \ 3723cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg1_name, arg1_val) 3733cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_ASYNC_STEP0(category, name, id, step) \ 3743cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ 3753cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_COPY, "step", step) 3763cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_ASYNC_STEP1(category, name, id, step, \ 3773cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg1_name, arg1_val) \ 3783cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP, \ 3793cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \ 3803cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg1_name, arg1_val) 3813cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 3823cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Records a single ASYNC_END event for "name" immediately. If the category 3833cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// is not enabled, then this does nothing. 3843cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_ASYNC_END0(category, name, id) \ 3853cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ 3863cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_NONE) 3873cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_ASYNC_END1(category, name, id, arg1_name, arg1_val) \ 3883cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ 3893cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val) 3903cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_ASYNC_END2(category, name, id, arg1_name, arg1_val, \ 3913cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) \ 3923cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ 3933cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_NONE, \ 3943cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg1_name, arg1_val, arg2_name, arg2_val) 3953cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_ASYNC_END0(category, name, id) \ 3963cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ 3973cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_COPY) 3983cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_ASYNC_END1(category, name, id, arg1_name, arg1_val) \ 3993cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ 4003cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_COPY, \ 4013cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg1_name, arg1_val) 4023cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_COPY_ASYNC_END2(category, name, id, arg1_name, arg1_val, \ 4033cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg2_name, arg2_val) \ 4043cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \ 4053cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick category, name, id, TRACE_EVENT_FLAG_COPY, \ 4063cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick arg1_name, arg1_val, arg2_name, arg2_val) 4073cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 4083cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Creates a scope of a sampling state with the given category and name (both must 4093cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// be constant strings). These states are intended for a sampling profiler. 4103cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Implementation note: we store category and name together because we don't 4113cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// want the inconsistency/expense of storing two pointers. 4123cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// |thread_bucket| is [0..2] and is used to statically isolate samples in one 4133cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// thread from others. 4143cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// 4153cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// { // The sampling state is set within this scope. 4163cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT_SAMPLING_STATE_SCOPE_FOR_BUCKET(0, "category", "name"); 4173cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// ...; 4183cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// } 4193cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, name) \ 4203cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TraceEvent::SamplingStateScope<bucket_number> traceEventSamplingScope(category "\0" name); 4213cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 4223cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Returns a current sampling state of the given bucket. 4233cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// The format of the returned string is "category\0name". 4243cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(bucket_number) \ 4253cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TraceEvent::SamplingStateScope<bucket_number>::current() 4263cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 4273cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Sets a current sampling state of the given bucket. 4283cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// |category| and |name| have to be constant strings. 4293cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET(bucket_number, category, name) \ 4303cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TraceEvent::SamplingStateScope<bucket_number>::set(category "\0" name) 4313cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 4323cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Sets a current sampling state of the given bucket. 4333cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// |categoryAndName| doesn't need to be a constant string. 4343cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// The format of the string is "category\0name". 4353cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_SET_NONCONST_SAMPLING_STATE_FOR_BUCKET(bucket_number, categoryAndName) \ 4363cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TraceEvent::SamplingStateScope<bucket_number>::set(categoryAndName) 4373cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 4383cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Syntactic sugars for the sampling tracing in the main thread. 4393cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_SCOPED_SAMPLING_STATE(category, name) \ 4403cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(0, category, name) 4413cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_GET_SAMPLING_STATE() \ 4423cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(0) 4433cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_SET_SAMPLING_STATE(category, name) \ 4443cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET(0, category, name) 4453cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_SET_NONCONST_SAMPLING_STATE(categoryAndName) \ 4463cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_EVENT_SET_NONCONST_SAMPLING_STATE_FOR_BUCKET(0, categoryAndName) 4473cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 4483cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick//////////////////////////////////////////////////////////////////////////////// 4493cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Implementation specific tracing API definitions. 4503cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 4513cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Get a pointer to the enabled state of the given trace category. Only 4523cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// long-lived literal strings should be given as the category name. The returned 4533cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// pointer can be held permanently in a local static for example. If the 4543cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// unsigned char is non-zero, tracing is enabled. If tracing is enabled, 4553cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled 4563cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// between the load of the tracing state and the call to 4573cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out 4583cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// for best performance when tracing is disabled. 4593cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// const unsigned char* 4603cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TRACE_EVENT_API_GET_CATEGORY_ENABLED(const char* category_name) 4613cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_API_GET_CATEGORY_ENABLED \ 4623cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick gl::TraceGetTraceCategoryEnabledFlag 4633cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 4643cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Add a trace event to the platform tracing system. 4653cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// void TRACE_EVENT_API_ADD_TRACE_EVENT( 4663cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// char phase, 4673cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// const unsigned char* category_enabled, 4683cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// const char* name, 4693cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// unsigned long long id, 4703cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// int num_args, 4713cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// const char** arg_names, 4723cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// const unsigned char* arg_types, 4733cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// const unsigned long long* arg_values, 4743cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// unsigned char flags) 4753cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_API_ADD_TRACE_EVENT \ 4763cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick gl::TraceAddTraceEvent 4773cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 4783cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick//////////////////////////////////////////////////////////////////////////////// 4793cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 4803cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Implementation detail: trace event macros create temporary variables 4813cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// to keep instrumentation overhead low. These macros give each temporary 4823cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// variable a unique name based on the line number to prevent name collissions. 4833cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define INTERNAL_TRACE_EVENT_UID3(a, b) \ 4843cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick trace_event_unique_##a##b 4853cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define INTERNAL_TRACE_EVENT_UID2(a, b) \ 4863cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_UID3(a, b) 4873cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define INTERNALTRACEEVENTUID(name_prefix) \ 4883cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__) 4893cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 4903cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Implementation detail: internal macro to create static category. 4913cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category) \ 4923cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick static const unsigned char* INTERNALTRACEEVENTUID(catstatic) = 0; \ 4933cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick if (!INTERNALTRACEEVENTUID(catstatic)) \ 4943cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNALTRACEEVENTUID(catstatic) = \ 4953cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_EVENT_API_GET_CATEGORY_ENABLED(category); 4963cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 4973cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Implementation detail: internal macro to create static category and add 4983cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// event if the category is enabled. 4993cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define INTERNAL_TRACE_EVENT_ADD(phase, category, name, flags, ...) \ 5003cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick do { \ 5013cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ 5023cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick if (*INTERNALTRACEEVENTUID(catstatic)) { \ 5033cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick gl::TraceEvent::addTraceEvent( \ 5043cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick phase, INTERNALTRACEEVENTUID(catstatic), name, \ 5053cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick gl::TraceEvent::noEventId, flags, ##__VA_ARGS__); \ 5063cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } \ 5073cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } while (0) 5083cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 5093cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Implementation detail: internal macro to create static category and add begin 5103cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// event if the category is enabled. Also adds the end event when the scope 5113cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// ends. 5123cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, ...) \ 5133cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ 5143cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick gl::TraceEvent::TraceEndOnScopeClose \ 5153cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNALTRACEEVENTUID(profileScope); \ 5163cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick if (*INTERNALTRACEEVENTUID(catstatic)) { \ 5173cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick gl::TraceEvent::addTraceEvent( \ 5183cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_EVENT_PHASE_BEGIN, \ 5193cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNALTRACEEVENTUID(catstatic), \ 5203cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick name, gl::TraceEvent::noEventId, \ 5213cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \ 5223cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNALTRACEEVENTUID(profileScope).initialize( \ 5233cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNALTRACEEVENTUID(catstatic), name); \ 5243cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } 5253cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 5263cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Implementation detail: internal macro to create static category and add 5273cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// event if the category is enabled. 5283cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category, name, id, flags, \ 5293cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick ...) \ 5303cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick do { \ 5313cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ 5323cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick if (*INTERNALTRACEEVENTUID(catstatic)) { \ 5333cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned char traceEventFlags = flags | TRACE_EVENT_FLAG_HAS_ID; \ 5343cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick gl::TraceEvent::TraceID traceEventTraceID( \ 5353cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick id, &traceEventFlags); \ 5363cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick gl::TraceEvent::addTraceEvent( \ 5373cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick phase, INTERNALTRACEEVENTUID(catstatic), \ 5383cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick name, traceEventTraceID.data(), traceEventFlags, \ 5393cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick ##__VA_ARGS__); \ 5403cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } \ 5413cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } while (0) 5423cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 5433cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Notes regarding the following definitions: 5443cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// New values can be added and propagated to third party libraries, but existing 5453cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// definitions must never be changed, because third party libraries may use old 5463cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// definitions. 5473cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 5483cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Phase indicates the nature of an event entry. E.g. part of a begin/end pair. 5493cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_PHASE_BEGIN ('B') 5503cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_PHASE_END ('E') 5513cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_PHASE_INSTANT ('I') 5523cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_PHASE_ASYNC_BEGIN ('S') 5533cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_PHASE_ASYNC_STEP ('T') 5543cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_PHASE_ASYNC_END ('F') 5553cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_PHASE_METADATA ('M') 5563cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_PHASE_COUNTER ('C') 5573cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_PHASE_SAMPLE ('P') 5583cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 5593cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT. 5603cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_FLAG_NONE (static_cast<unsigned char>(0)) 5613cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_FLAG_COPY (static_cast<unsigned char>(1 << 0)) 5623cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_FLAG_HAS_ID (static_cast<unsigned char>(1 << 1)) 5633cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_EVENT_FLAG_MANGLE_ID (static_cast<unsigned char>(1 << 2)) 5643cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 5653cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Type values for identifying types in the TraceValue union. 5663cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_VALUE_TYPE_BOOL (static_cast<unsigned char>(1)) 5673cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_VALUE_TYPE_UINT (static_cast<unsigned char>(2)) 5683cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_VALUE_TYPE_INT (static_cast<unsigned char>(3)) 5693cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_VALUE_TYPE_DOUBLE (static_cast<unsigned char>(4)) 5703cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_VALUE_TYPE_POINTER (static_cast<unsigned char>(5)) 5713cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_VALUE_TYPE_STRING (static_cast<unsigned char>(6)) 5723cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define TRACE_VALUE_TYPE_COPY_STRING (static_cast<unsigned char>(7)) 5733cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 5743cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 5753cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patricknamespace gl { 5763cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 5773cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patricknamespace TraceEvent { 5783cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 5793cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Specify these values when the corresponding argument of addTraceEvent is not 5803cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// used. 5813cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickconst int zeroNumArgs = 0; 5823cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickconst unsigned long long noEventId = 0; 5833cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 5843cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TraceID encapsulates an ID that can either be an integer or pointer. Pointers 5853cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// are mangled with the Process ID so that they are unlikely to collide when the 5863cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// same pointer is used on different processes. 5873cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickclass TraceID { 5883cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickpublic: 5893cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick explicit TraceID(const void* id, unsigned char* flags) : 5903cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick m_data(static_cast<unsigned long long>(reinterpret_cast<unsigned long>(id))) 5913cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick { 5923cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick *flags |= TRACE_EVENT_FLAG_MANGLE_ID; 5933cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } 5943cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick explicit TraceID(unsigned long long id, unsigned char* flags) : m_data(id) { (void)flags; } 5953cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick explicit TraceID(unsigned long id, unsigned char* flags) : m_data(id) { (void)flags; } 5963cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick explicit TraceID(unsigned int id, unsigned char* flags) : m_data(id) { (void)flags; } 5973cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick explicit TraceID(unsigned short id, unsigned char* flags) : m_data(id) { (void)flags; } 5983cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick explicit TraceID(unsigned char id, unsigned char* flags) : m_data(id) { (void)flags; } 5993cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick explicit TraceID(long long id, unsigned char* flags) : 6003cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick m_data(static_cast<unsigned long long>(id)) { (void)flags; } 6013cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick explicit TraceID(long id, unsigned char* flags) : 6023cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick m_data(static_cast<unsigned long long>(id)) { (void)flags; } 6033cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick explicit TraceID(int id, unsigned char* flags) : 6043cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick m_data(static_cast<unsigned long long>(id)) { (void)flags; } 6053cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick explicit TraceID(short id, unsigned char* flags) : 6063cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick m_data(static_cast<unsigned long long>(id)) { (void)flags; } 6073cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick explicit TraceID(signed char id, unsigned char* flags) : 6083cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick m_data(static_cast<unsigned long long>(id)) { (void)flags; } 6093cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 6103cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned long long data() const { return m_data; } 6113cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 6123cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickprivate: 6133cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned long long m_data; 6143cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick}; 6153cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 6163cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Simple union to store various types as unsigned long long. 6173cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickunion TraceValueUnion { 6183cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick bool m_bool; 6193cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned long long m_uint; 6203cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick long long m_int; 6213cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick double m_double; 6223cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const void* m_pointer; 6233cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const char* m_string; 6243cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick}; 6253cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 6263cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Simple container for const char* that should be copied instead of retained. 6273cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickclass TraceStringWithCopy { 6283cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickpublic: 6293cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick explicit TraceStringWithCopy(const char* str) : m_str(str) { } 6303cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick operator const char* () const { return m_str; } 6313cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickprivate: 6323cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const char* m_str; 6333cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick}; 6343cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 6353cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Define setTraceValue for each allowed type. It stores the type and 6363cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// value in the return arguments. This allows this API to avoid declaring any 6373cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// structures so that it is portable to third_party libraries. 6383cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, \ 6393cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick union_member, \ 6403cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick value_type_id) \ 6413cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick static inline void setTraceValue(actual_type arg, \ 6423cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned char* type, \ 6433cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned long long* value) { \ 6443cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TraceValueUnion typeValue; \ 6453cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick typeValue.union_member = arg; \ 6463cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick *type = value_type_id; \ 6473cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick *value = typeValue.m_uint; \ 6483cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } 6493cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Simpler form for int types that can be safely casted. 6503cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, \ 6513cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick value_type_id) \ 6523cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick static inline void setTraceValue(actual_type arg, \ 6533cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned char* type, \ 6543cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned long long* value) { \ 6553cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick *type = value_type_id; \ 6563cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick *value = static_cast<unsigned long long>(arg); \ 6573cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } 6583cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 6593cf1f4eac8d79432626fcb8b0bc12482fafd2392Al PatrickINTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT) 6603cf1f4eac8d79432626fcb8b0bc12482fafd2392Al PatrickINTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT) 6613cf1f4eac8d79432626fcb8b0bc12482fafd2392Al PatrickINTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT) 6623cf1f4eac8d79432626fcb8b0bc12482fafd2392Al PatrickINTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT) 6633cf1f4eac8d79432626fcb8b0bc12482fafd2392Al PatrickINTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT) 6643cf1f4eac8d79432626fcb8b0bc12482fafd2392Al PatrickINTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT) 6653cf1f4eac8d79432626fcb8b0bc12482fafd2392Al PatrickINTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT) 6663cf1f4eac8d79432626fcb8b0bc12482fafd2392Al PatrickINTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT) 6673cf1f4eac8d79432626fcb8b0bc12482fafd2392Al PatrickINTERNAL_DECLARE_SET_TRACE_VALUE(bool, m_bool, TRACE_VALUE_TYPE_BOOL) 6683cf1f4eac8d79432626fcb8b0bc12482fafd2392Al PatrickINTERNAL_DECLARE_SET_TRACE_VALUE(double, m_double, TRACE_VALUE_TYPE_DOUBLE) 6693cf1f4eac8d79432626fcb8b0bc12482fafd2392Al PatrickINTERNAL_DECLARE_SET_TRACE_VALUE(const void*, m_pointer, 6703cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_VALUE_TYPE_POINTER) 6713cf1f4eac8d79432626fcb8b0bc12482fafd2392Al PatrickINTERNAL_DECLARE_SET_TRACE_VALUE(const char*, m_string, 6723cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_VALUE_TYPE_STRING) 6733cf1f4eac8d79432626fcb8b0bc12482fafd2392Al PatrickINTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, m_string, 6743cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_VALUE_TYPE_COPY_STRING) 6753cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 6763cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#undef INTERNAL_DECLARE_SET_TRACE_VALUE 6773cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT 6783cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 6793cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickstatic inline void setTraceValue(const std::string& arg, 6803cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned char* type, 6813cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned long long* value) { 6823cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TraceValueUnion typeValue; 6833cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick typeValue.m_string = arg.data(); 6843cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick *type = TRACE_VALUE_TYPE_COPY_STRING; 6853cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick *value = typeValue.m_uint; 6863cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick} 6873cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 6883cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// These addTraceEvent template functions are defined here instead of in the 6893cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// macro, because the arg values could be temporary string objects. In order to 6903cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// store pointers to the internal c_str and pass through to the tracing API, the 6913cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// arg values must live throughout these procedures. 6923cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 6933cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickstatic inline void addTraceEvent(char phase, 6943cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const unsigned char* categoryEnabled, 6953cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const char* name, 6963cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned long long id, 6973cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned char flags) { 6983cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_EVENT_API_ADD_TRACE_EVENT( 6993cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick phase, categoryEnabled, name, id, 7003cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick zeroNumArgs, 0, 0, 0, 7013cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick flags); 7023cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick} 7033cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 7043cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patricktemplate<class ARG1_TYPE> 7053cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickstatic inline void addTraceEvent(char phase, 7063cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const unsigned char* categoryEnabled, 7073cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const char* name, 7083cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned long long id, 7093cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned char flags, 7103cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const char* arg1Name, 7113cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const ARG1_TYPE& arg1Val) { 7123cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const int numArgs = 1; 7133cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned char argTypes[1]; 7143cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned long long argValues[1]; 7153cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick setTraceValue(arg1Val, &argTypes[0], &argValues[0]); 7163cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_EVENT_API_ADD_TRACE_EVENT( 7173cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick phase, categoryEnabled, name, id, 7183cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick numArgs, &arg1Name, argTypes, argValues, 7193cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick flags); 7203cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick} 7213cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 7223cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patricktemplate<class ARG1_TYPE, class ARG2_TYPE> 7233cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickstatic inline void addTraceEvent(char phase, 7243cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const unsigned char* categoryEnabled, 7253cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const char* name, 7263cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned long long id, 7273cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned char flags, 7283cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const char* arg1Name, 7293cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const ARG1_TYPE& arg1Val, 7303cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const char* arg2Name, 7313cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const ARG2_TYPE& arg2Val) { 7323cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const int numArgs = 2; 7333cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const char* argNames[2] = { arg1Name, arg2Name }; 7343cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned char argTypes[2]; 7353cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick unsigned long long argValues[2]; 7363cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick setTraceValue(arg1Val, &argTypes[0], &argValues[0]); 7373cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick setTraceValue(arg2Val, &argTypes[1], &argValues[1]); 7383cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick return TRACE_EVENT_API_ADD_TRACE_EVENT( 7393cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick phase, categoryEnabled, name, id, 7403cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick numArgs, argNames, argTypes, argValues, 7413cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick flags); 7423cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick} 7433cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 7443cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// Used by TRACE_EVENTx macro. Do not use directly. 7453cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickclass TraceEndOnScopeClose { 7463cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickpublic: 7473cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick // Note: members of m_data intentionally left uninitialized. See initialize. 7483cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TraceEndOnScopeClose() : m_pdata(0) { } 7493cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick ~TraceEndOnScopeClose() 7503cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick { 7513cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick if (m_pdata) 7523cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick addEventIfEnabled(); 7533cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } 7543cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 7553cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick void initialize(const unsigned char* categoryEnabled, 7563cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const char* name) 7573cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick { 7583cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick m_data.categoryEnabled = categoryEnabled; 7593cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick m_data.name = name; 7603cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick m_pdata = &m_data; 7613cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } 7623cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 7633cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickprivate: 7643cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick // Add the end event if the category is still enabled. 7653cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick void addEventIfEnabled() 7663cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick { 7673cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick // Only called when m_pdata is non-null. 7683cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick if (*m_pdata->categoryEnabled) { 7693cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_EVENT_API_ADD_TRACE_EVENT( 7703cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_EVENT_PHASE_END, 7713cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick m_pdata->categoryEnabled, 7723cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick m_pdata->name, noEventId, 7733cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick zeroNumArgs, 0, 0, 0, 7743cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick TRACE_EVENT_FLAG_NONE); 7753cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } 7763cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } 7773cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 7783cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick // This Data struct workaround is to avoid initializing all the members 7793cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick // in Data during construction of this object, since this object is always 7803cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick // constructed, even when tracing is disabled. If the members of Data were 7813cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick // members of this class instead, compiler warnings occur about potential 7823cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick // uninitialized accesses. 7833cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick struct Data { 7843cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const unsigned char* categoryEnabled; 7853cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const char* name; 7863cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick }; 7873cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick Data* m_pdata; 7883cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick Data m_data; 7893cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick}; 7903cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 7913cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// TraceEventSamplingStateScope records the current sampling state 7923cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// and sets a new sampling state. When the scope exists, it restores 7933cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick// the sampling state having recorded. 7943cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patricktemplate<size_t BucketNumber> 7953cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickclass SamplingStateScope { 7963cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickpublic: 7973cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick SamplingStateScope(const char* categoryAndName) 7983cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick { 7993cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick m_previousState = SamplingStateScope<BucketNumber>::current(); 8003cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick SamplingStateScope<BucketNumber>::set(categoryAndName); 8013cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } 8023cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 8033cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick ~SamplingStateScope() 8043cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick { 8053cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick SamplingStateScope<BucketNumber>::set(m_previousState); 8063cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } 8073cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 8083cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick // FIXME: Make load/store to traceSamplingState[] thread-safe and atomic. 8093cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick static inline const char* current() 8103cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick { 8113cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick return reinterpret_cast<const char*>(*gl::traceSamplingState[BucketNumber]); 8123cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } 8133cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick static inline void set(const char* categoryAndName) 8143cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick { 8153cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick *gl::traceSamplingState[BucketNumber] = reinterpret_cast<long>(const_cast<char*>(categoryAndName)); 8163cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick } 8173cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 8183cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrickprivate: 8193cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick const char* m_previousState; 8203cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick}; 8213cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 8223cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick} // namespace TraceEvent 8233cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 8243cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick} // namespace gl 8253cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick 8263cf1f4eac8d79432626fcb8b0bc12482fafd2392Al Patrick#endif 827