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