15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This header file defines the set of trace_event macros without specifying
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// how the events actually get collected and stored. If you need to expose trace
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// events to some other universe, you can copy-and-paste this file as well as
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// trace_event.h, modifying the macros contained there as necessary for the
9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// target platform. The end result is that multiple libraries can funnel events
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// through to a shared trace event collector.
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Trace events are for tracking application performance and resource usage.
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Macros are provided to track:
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//    Begin and end of function calls
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//    Counters
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Events are issued against categories. Whereas LOG's
18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// categories are statically defined, TRACE categories are created
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// implicitly with a string. For example:
20ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//   TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent",
21ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch//                        TRACE_EVENT_SCOPE_THREAD)
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// It is often the case that one trace may belong in multiple categories at the
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// same time. The first argument to the trace can be a comma-separated list of
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// categories, forming a category group, like:
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
27ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// TRACE_EVENT_INSTANT0("input,views", "OnMouseOver", TRACE_EVENT_SCOPE_THREAD)
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// We can enable/disable tracing of OnMouseOver by enabling/disabling either
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// category.
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Events can be INSTANT, or can be pairs of BEGIN and END in the same scope:
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly")
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   doSomethingCostly()
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly")
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Note: our tools can't always determine the correct BEGIN/END pairs unless
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// these are used in the same scope. Use ASYNC_BEGIN/ASYNC_END macros if you
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// need them to be in separate scopes.
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A common use case is to trace entire function scopes. This
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// issues a trace BEGIN and END automatically:
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   void doSomethingCostly() {
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly");
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     ...
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   }
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Additional parameters can be associated with an event:
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   void doSomethingCostly2(int howMuch) {
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly",
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//         "howMuch", howMuch);
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     ...
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   }
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The trace system will automatically add to this information the
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// current process id, thread id, and a timestamp in microseconds.
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// To trace an asynchronous procedure such as an IPC send/receive, use
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ASYNC_BEGIN and ASYNC_END:
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   [single threaded sender code]
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     static int send_count = 0;
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     ++send_count;
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     TRACE_EVENT_ASYNC_BEGIN0("ipc", "message", send_count);
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     Send(new MyMessage(send_count));
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   [receive code]
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     void OnMyMessage(send_count) {
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//       TRACE_EVENT_ASYNC_END0("ipc", "message", send_count);
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     }
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The third parameter is a unique ID to match ASYNC_BEGIN/ASYNC_END pairs.
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ASYNC_BEGIN and ASYNC_END can occur on any thread of any traced process.
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Pointers can be used for the ID parameter, and they will be mangled
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// internally so that the same pointer on two different processes will not
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// match. For example:
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   class MyTracedClass {
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//    public:
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     MyTracedClass() {
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//       TRACE_EVENT_ASYNC_BEGIN0("category", "MyTracedClass", this);
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     }
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     ~MyTracedClass() {
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//       TRACE_EVENT_ASYNC_END0("category", "MyTracedClass", this);
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     }
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   }
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Trace event also supports counters, which is a way to track a quantity
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// as it varies over time. Counters are created with the following macro:
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter", g_myCounterValue);
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Counters are process-specific. The macro itself can be issued from any
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// thread, however.
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Sometimes, you want to track two counters at once. You can do this with two
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// counter macros:
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter0", g_myCounterValue[0]);
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   TRACE_COUNTER1("MY_SUBSYSTEM", "myCounter1", g_myCounterValue[1]);
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Or you can do it with a combined macro:
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   TRACE_COUNTER2("MY_SUBSYSTEM", "myCounter",
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//       "bytesPinned", g_myCounterValue[0],
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//       "bytesAllocated", g_myCounterValue[1]);
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This indicates to the tracing UI that these counters should be displayed
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// in a single graph, as a summed area chart.
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
101ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Since counters are in a global namespace, you may want to disambiguate with a
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// unique ID, by using the TRACE_COUNTER_ID* variations.
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// By default, trace collection is compiled in, but turned off at runtime.
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Collecting trace data is the responsibility of the embedding
106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// application. In Chrome's case, navigating to about:tracing will turn on
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// tracing and display data collected across all active processes.
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Memory scoping note:
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Tracing copies the pointers, not the string content, of the strings passed
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// in for category_group, name, and arg_names.  Thus, the following code will
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// cause problems:
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     char* str = strdup("importantName");
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     TRACE_EVENT_INSTANT0("SUBSYSTEM", str);  // BAD!
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     free(str);                   // Trace system now has dangling pointer
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// To avoid this issue with the |name| and |arg_name| parameters, use the
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TRACE_EVENT_COPY_XXX overloads of the macros at additional runtime overhead.
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Notes: The category must always be in a long-lived char* (i.e. static const).
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//        The |arg_values|, when used, are always deep copied with the _COPY
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//        macros.
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// When are string argument values copied:
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// const char* arg_values are only referenced by default:
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     TRACE_EVENT1("category", "name",
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//                  "arg1", "literal string is only referenced");
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use TRACE_STR_COPY to force copying of a const char*:
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     TRACE_EVENT1("category", "name",
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//                  "arg1", TRACE_STR_COPY("string will be copied"));
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// std::string arg_values are always copied:
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     TRACE_EVENT1("category", "name",
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//                  "arg1", std::string("string will be copied"));
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
1368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Convertable notes:
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Converting a large data type to a string can be costly. To help with this,
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the trace framework provides an interface ConvertableToTraceFormat. If you
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// inherit from it and implement the AppendAsTraceFormat method the trace
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// framework will call back to your object to convert a trace output time. This
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// means, if the category for the event is disabled, the conversion will not
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// happen.
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   class MyData : public base::debug::ConvertableToTraceFormat {
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//    public:
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     MyData() {}
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     virtual void AppendAsTraceFormat(std::string* out) const OVERRIDE {
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//       out->append("{\"foo\":1}");
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     }
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//    private:
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)//     virtual ~MyData() {}
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     DISALLOW_COPY_AND_ASSIGN(MyData);
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   };
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   TRACE_EVENT1("foo", "bar", "data",
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)//                scoped_refptr<ConvertableToTraceFormat>(new MyData()));
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The trace framework will take ownership if the passed pointer and it will
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// be free'd when the trace buffer is flushed.
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Note, we only do the conversion when the buffer is flushed, so the provided
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// data object should not be modified after it's passed to the trace framework.
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Thread Safety:
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// A thread safe singleton and mutex are used for thread safety. Category
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// enabled flags are used to limit the performance impact when the system
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// is not enabled.
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TRACE_EVENT macros first cache a pointer to a category. The categories are
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// statically allocated and safe at all times, even after exit. Fetching a
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// category is protected by the TraceLog::lock_. Multiple threads initializing
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the static variable is safe, as they will be serialized by the lock and
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// multiple calls will return the same pointer to the category.
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Then the category_group_enabled flag is checked. This is a unsigned char, and
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// not intended to be multithread safe. It optimizes access to AddTraceEvent
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// which is threadsafe internally via TraceLog::lock_. The enabled flag may
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// cause some threads to incorrectly call or skip calling AddTraceEvent near
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the time of the system being enabled or disabled. This is acceptable as
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// we tolerate some data loss while the system is being enabled/disabled and
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// because AddTraceEvent is threadsafe internally and checks the enabled state
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// again under lock.
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Without the use of these static category pointers and enabled flags all
186ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// trace points would carry a significant performance cost of acquiring a lock
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// and resolving the category.
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_DEBUG_TRACE_EVENT_H_
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_DEBUG_TRACE_EVENT_H_
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string>
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/atomicops.h"
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event_impl.h"
196bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/debug/trace_event_memory.h"
197d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/debug/trace_event_system_stats_monitor.h"
19823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "base/time/time.h"
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// By default, const char* argument values are assumed to have long-lived scope
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// and will not be copied. Use this macro to force a const char* to be copied.
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_STR_COPY(str) \
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    trace_event_internal::TraceStringWithCopy(str)
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
206b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// This will mark the trace event as disabled by default. The user will need
207b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// to explicitly enable the event.
208b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#define TRACE_DISABLED_BY_DEFAULT(name) "disabled-by-default-" name
209b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// By default, uint64 ID argument values are not mangled with the Process ID in
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TRACE_EVENT_ASYNC macros. Use this macro to force Process ID mangling.
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_ID_MANGLE(id) \
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    trace_event_internal::TraceID::ForceMangle(id)
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// By default, pointers are mangled with the Process ID in TRACE_EVENT_ASYNC
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// macros. Use this macro to prevent Process ID mangling.
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_ID_DONT_MANGLE(id) \
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    trace_event_internal::TraceID::DontMangle(id)
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Records a pair of begin and end events called "name" for the current
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// scope, with 0, 1 or 2 associated arguments. If the category is not
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// enabled, then this does nothing.
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - category and name strings must have application lifetime (statics or
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   literals). They may not include " chars.
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT0(category_group, name) \
226bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    INTERNAL_TRACE_MEMORY(category_group, name) \
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name)
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
229bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    INTERNAL_TRACE_MEMORY(category_group, name) \
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val)
231bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#define TRACE_EVENT2( \
232bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    category_group, name, arg1_name, arg1_val, arg2_name, arg2_val) \
233bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  INTERNAL_TRACE_MEMORY(category_group, name) \
234bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  INTERNAL_TRACE_EVENT_ADD_SCOPED( \
235bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch      category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
237424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Records events like TRACE_EVENT2 but uses |memory_tag| for memory tracing.
238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Use this where |name| is too generic to accurately aggregate allocations.
239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#define TRACE_EVENT_WITH_MEMORY_TAG2( \
240424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    category, name, memory_tag, arg1_name, arg1_val, arg2_name, arg2_val) \
241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  INTERNAL_TRACE_MEMORY(category, memory_tag) \
242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  INTERNAL_TRACE_EVENT_ADD_SCOPED( \
243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      category, name, arg1_name, arg1_val, arg2_name, arg2_val)
244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// UNSHIPPED_TRACE_EVENT* are like TRACE_EVENT* except that they are not
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// included in official builds.
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if OFFICIAL_BUILD
2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#undef TRACING_IS_OFFICIAL_BUILD
2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#define TRACING_IS_OFFICIAL_BUILD 1
2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#elif !defined(TRACING_IS_OFFICIAL_BUILD)
2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#define TRACING_IS_OFFICIAL_BUILD 0
2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if TRACING_IS_OFFICIAL_BUILD
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UNSHIPPED_TRACE_EVENT0(category_group, name) (void)0
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UNSHIPPED_TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    (void)0
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UNSHIPPED_TRACE_EVENT2(category_group, name, arg1_name, arg1_val, \
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               arg2_name, arg2_val) (void)0
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UNSHIPPED_TRACE_EVENT_INSTANT0(category_group, name, scope) (void)0
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UNSHIPPED_TRACE_EVENT_INSTANT1(category_group, name, scope, \
263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       arg1_name, arg1_val) (void)0
264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UNSHIPPED_TRACE_EVENT_INSTANT2(category_group, name, scope, \
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       arg1_name, arg1_val, \
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       arg2_name, arg2_val) (void)0
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UNSHIPPED_TRACE_EVENT0(category_group, name) \
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT0(category_group, name)
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UNSHIPPED_TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT1(category_group, name, arg1_name, arg1_val)
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UNSHIPPED_TRACE_EVENT2(category_group, name, arg1_name, arg1_val, \
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                               arg2_name, arg2_val) \
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UNSHIPPED_TRACE_EVENT_INSTANT0(category_group, name, scope) \
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT_INSTANT0(category_group, name, scope)
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UNSHIPPED_TRACE_EVENT_INSTANT1(category_group, name, scope, \
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       arg1_name, arg1_val) \
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val)
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define UNSHIPPED_TRACE_EVENT_INSTANT2(category_group, name, scope, \
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       arg1_name, arg1_val, \
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       arg2_name, arg2_val) \
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         arg2_name, arg2_val)
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Records a single event called "name" immediately, with 0, 1 or 2
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// associated arguments. If the category is not enabled, then this
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// does nothing.
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - category and name strings must have application lifetime (statics or
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   literals). They may not include " chars.
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_INSTANT0(category_group, name, scope) \
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_NONE | scope)
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_INSTANT1(category_group, name, scope, arg1_name, arg1_val) \
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_NONE | scope, \
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val)
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_INSTANT2(category_group, name, scope, arg1_name, arg1_val, \
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             arg2_name, arg2_val) \
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_NONE | scope, \
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val, arg2_name, arg2_val)
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_INSTANT0(category_group, name, scope) \
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_COPY | scope)
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_INSTANT1(category_group, name, scope, \
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  arg1_name, arg1_val) \
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_COPY | scope, arg1_name, \
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_val)
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_INSTANT2(category_group, name, scope, \
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  arg1_name, arg1_val, \
314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  arg2_name, arg2_val) \
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_INSTANT, \
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_COPY | scope, \
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val, arg2_name, arg2_val)
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Sets the current sample state to the given category and name (both must be
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// constant strings). These states are intended for a sampling profiler.
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Implementation note: we store category and name together because we don't
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// want the inconsistency/expense of storing two pointers.
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// |thread_bucket| is [0..2] and is used to statically isolate samples in one
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// thread from others.
3257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#define TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET( \
3267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bucket_number, category, name)                 \
3277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        trace_event_internal::                     \
3287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        TraceEventSamplingStateScope<bucket_number>::Set(category "\0" name)
3297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Returns a current sampling state of the given bucket.
3317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#define TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(bucket_number) \
3327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    trace_event_internal::TraceEventSamplingStateScope<bucket_number>::Current()
3337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Creates a scope of a sampling state of the given bucket.
3357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//
3367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// {  // The sampling state is set within this scope.
3377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//    TRACE_EVENT_SAMPLING_STATE_SCOPE_FOR_BUCKET(0, "category", "name");
3387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch//    ...;
3397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// }
3407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#define TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(                   \
3417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    bucket_number, category, name)                                      \
3427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    trace_event_internal::TraceEventSamplingStateScope<bucket_number>   \
3437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        traceEventSamplingScope(category "\0" name);
3447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Syntactic sugars for the sampling tracing in the main thread.
3467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#define TRACE_EVENT_SCOPED_SAMPLING_STATE(category, name) \
3477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TRACE_EVENT_SCOPED_SAMPLING_STATE_FOR_BUCKET(0, category, name)
3487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#define TRACE_EVENT_GET_SAMPLING_STATE() \
3497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TRACE_EVENT_GET_SAMPLING_STATE_FOR_BUCKET(0)
3507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#define TRACE_EVENT_SET_SAMPLING_STATE(category, name) \
3517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TRACE_EVENT_SET_SAMPLING_STATE_FOR_BUCKET(0, category, name)
3527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Records a single BEGIN event called "name" immediately, with 0, 1 or 2
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// associated arguments. If the category is not enabled, then this
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// does nothing.
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - category and name strings must have application lifetime (statics or
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   literals). They may not include " chars.
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_BEGIN0(category_group, name) \
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_NONE)
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_BEGIN1(category_group, name, arg1_name, arg1_val) \
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_BEGIN2(category_group, name, arg1_name, arg1_val, \
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg2_name, arg2_val) \
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg2_name, arg2_val)
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_BEGIN0(category_group, name) \
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_COPY)
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_BEGIN1(category_group, name, arg1_name, arg1_val) \
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_BEGIN2(category_group, name, arg1_name, arg1_val, \
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg2_name, arg2_val) \
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_BEGIN, \
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg2_name, arg2_val)
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Similar to TRACE_EVENT_BEGINx but with a custom |at| timestamp provided.
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - |id| is used to match the _BEGIN event with the _END event.
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   Events are considered to match if their category_group, name and id values
385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   all match. |id| must either be a pointer or an integer value up to 64 bits.
386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   If it's a pointer, the bits will be xored with a hash of the process ID so
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   that the same pointer on two different processes will not collide.
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_BEGIN_WITH_ID_TID_AND_TIMESTAMP0(category_group, \
389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        name, id, thread_id, timestamp) \
390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \
392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        timestamp, TRACE_EVENT_FLAG_NONE)
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_BEGIN_WITH_ID_TID_AND_TIMESTAMP0( \
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, thread_id, timestamp) \
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        TRACE_EVENT_PHASE_ASYNC_BEGIN, category_group, name, id, thread_id, \
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        timestamp, TRACE_EVENT_FLAG_COPY)
398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Records a single END event for "name" immediately. If the category
400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// is not enabled, then this does nothing.
401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - category and name strings must have application lifetime (statics or
402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   literals). They may not include " chars.
403c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_END0(category_group, name) \
404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_NONE)
406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_END1(category_group, name, arg1_name, arg1_val) \
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_END2(category_group, name, arg1_name, arg1_val, \
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg2_name, arg2_val) \
411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
412c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val, \
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg2_name, arg2_val)
414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_END0(category_group, name) \
415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_COPY)
417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_END1(category_group, name, arg1_name, arg1_val) \
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val)
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_END2(category_group, name, arg1_name, arg1_val, \
421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg2_name, arg2_val) \
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_END, \
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_COPY, arg1_name, arg1_val, \
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg2_name, arg2_val)
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Similar to TRACE_EVENT_ENDx but with a custom |at| timestamp provided.
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - |id| is used to match the _BEGIN event with the _END event.
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   Events are considered to match if their category_group, name and id values
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   all match. |id| must either be a pointer or an integer value up to 64 bits.
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   If it's a pointer, the bits will be xored with a hash of the process ID so
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   that the same pointer on two different processes will not collide.
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_END_WITH_ID_TID_AND_TIMESTAMP0(category_group, \
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        name, id, thread_id, timestamp) \
434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id, \
436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        timestamp, TRACE_EVENT_FLAG_NONE)
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_END_WITH_ID_TID_AND_TIMESTAMP0( \
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, thread_id, timestamp) \
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        TRACE_EVENT_PHASE_ASYNC_END, category_group, name, id, thread_id, \
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        timestamp, TRACE_EVENT_FLAG_COPY)
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Records the value of a counter called "name" immediately. Value
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// must be representable as a 32 bit integer.
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - category and name strings must have application lifetime (statics or
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   literals). They may not include " chars.
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_COUNTER1(category_group, name, value) \
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_NONE, \
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "value", static_cast<int>(value))
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_COPY_COUNTER1(category_group, name, value) \
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_COPY, \
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "value", static_cast<int>(value))
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Records the values of a multi-parted counter called "name" immediately.
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The UI will treat value1 and value2 as parts of a whole, displaying their
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// values as a stacked-bar chart.
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - category and name strings must have application lifetime (statics or
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   literals). They may not include " chars.
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_COUNTER2(category_group, name, value1_name, value1_val, \
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        value2_name, value2_val) \
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_NONE, \
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        value1_name, static_cast<int>(value1_val), \
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        value2_name, static_cast<int>(value2_val))
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_COPY_COUNTER2(category_group, name, value1_name, value1_val, \
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        value2_name, value2_val) \
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD(TRACE_EVENT_PHASE_COUNTER, \
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_EVENT_FLAG_COPY, \
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        value1_name, static_cast<int>(value1_val), \
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        value2_name, static_cast<int>(value2_val))
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Records the value of a counter called "name" immediately. Value
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// must be representable as a 32 bit integer.
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - category and name strings must have application lifetime (statics or
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   literals). They may not include " chars.
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - |id| is used to disambiguate counters with the same name. It must either
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   will be xored with a hash of the process ID so that the same pointer on
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   two different processes will not collide.
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_COUNTER_ID1(category_group, name, id, value) \
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, \
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "value", static_cast<int>(value))
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_COPY_COUNTER_ID1(category_group, name, id, value) \
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY, \
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "value", static_cast<int>(value))
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Records the values of a multi-parted counter called "name" immediately.
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The UI will treat value1 and value2 as parts of a whole, displaying their
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// values as a stacked-bar chart.
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - category and name strings must have application lifetime (statics or
495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   literals). They may not include " chars.
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - |id| is used to disambiguate counters with the same name. It must either
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   be a pointer or an integer value up to 64 bits. If it's a pointer, the bits
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   will be xored with a hash of the process ID so that the same pointer on
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   two different processes will not collide.
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_COUNTER_ID2(category_group, name, id, value1_name, value1_val, \
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        value2_name, value2_val) \
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, \
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        value1_name, static_cast<int>(value1_val), \
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        value2_name, static_cast<int>(value2_val))
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_COPY_COUNTER_ID2(category_group, name, id, value1_name, \
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        value1_val, value2_name, value2_val) \
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_COUNTER, \
509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY, \
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        value1_name, static_cast<int>(value1_val), \
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        value2_name, static_cast<int>(value2_val))
512c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Records a single ASYNC_BEGIN event called "name" immediately, with 0, 1 or 2
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// associated arguments. If the category is not enabled, then this
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// does nothing.
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - category and name strings must have application lifetime (statics or
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   literals). They may not include " chars.
519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - |id| is used to match the ASYNC_BEGIN event with the ASYNC_END event. ASYNC
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   events are considered to match if their category_group, name and id values
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   all match. |id| must either be a pointer or an integer value up to 64 bits.
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   If it's a pointer, the bits will be xored with a hash of the process ID so
523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   that the same pointer on two different processes will not collide.
5241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)//
525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// An asynchronous operation can consist of multiple phases. The first phase is
526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// defined by the ASYNC_BEGIN calls. Additional phases can be defined using the
5271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// ASYNC_STEP_INTO or ASYNC_STEP_PAST macros. The ASYNC_STEP_INTO macro will
5281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// annotate the block following the call. The ASYNC_STEP_PAST macro will
5291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// annotate the block prior to the call. Note that any particular event must use
5301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// only STEP_INTO or STEP_PAST macros; they can not mix and match. When the
5311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// operation completes, call ASYNC_END.
5321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)//
5331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// An ASYNC trace typically occurs on a single thread (if not, they will only be
534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// drawn on the thread defined in the ASYNC_BEGIN event), but all events in that
5351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// operation must use the same |name| and |id|. Each step can have its own
536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// args.
537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_ASYNC_BEGIN0(category_group, name, id) \
538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE)
540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_val) \
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_val, arg2_name, arg2_val) \
546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, \
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val, arg2_name, arg2_val)
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_ASYNC_BEGIN0(category_group, name, id) \
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY)
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_ASYNC_BEGIN1(category_group, name, id, arg1_name, \
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_val) \
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY, \
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val)
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_ASYNC_BEGIN2(category_group, name, id, arg1_name, \
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_val, arg2_name, arg2_val) \
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_BEGIN, \
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY, \
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val, arg2_name, arg2_val)
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Records a single ASYNC_STEP_INTO event for |step| immediately. If the
5641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// category is not enabled, then this does nothing. The |name| and |id| must
5651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// match the ASYNC_BEGIN event above. The |step| param identifies this step
5661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// within the async event. This should be called at the beginning of the next
5671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// phase of an asynchronous operation. The ASYNC_BEGIN event must not have any
5681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// ASYNC_STEP_PAST events.
5691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#define TRACE_EVENT_ASYNC_STEP_INTO0(category_group, name, id, step) \
5701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP_INTO, \
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step)
5721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#define TRACE_EVENT_ASYNC_STEP_INTO1(category_group, name, id, step, \
5731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                     arg1_name, arg1_val) \
5741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP_INTO, \
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val)
577b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
5781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Records a single ASYNC_STEP_PAST event for |step| immediately. If the
5791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// category is not enabled, then this does nothing. The |name| and |id| must
5801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// match the ASYNC_BEGIN event above. The |step| param identifies this step
5811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// within the async event. This should be called at the beginning of the next
5821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// phase of an asynchronous operation. The ASYNC_BEGIN event must not have any
5831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// ASYNC_STEP_INTO events.
5841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#define TRACE_EVENT_ASYNC_STEP_PAST0(category_group, name, id, step) \
5851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP_PAST, \
5861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step)
5871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#define TRACE_EVENT_ASYNC_STEP_PAST1(category_group, name, id, step, \
5881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                     arg1_name, arg1_val) \
5891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_STEP_PAST, \
5901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val)
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Records a single ASYNC_END event for "name" immediately. If the category
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// is not enabled, then this does nothing.
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_ASYNC_END0(category_group, name, id) \
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE)
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_ASYNC_END1(category_group, name, id, arg1_name, arg1_val) \
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_ASYNC_END2(category_group, name, id, arg1_name, arg1_val, \
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg2_name, arg2_val) \
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, \
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val, arg2_name, arg2_val)
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_ASYNC_END0(category_group, name, id) \
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY)
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_ASYNC_END1(category_group, name, id, arg1_name, \
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_val) \
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY, \
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val)
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_ASYNC_END2(category_group, name, id, arg1_name, \
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_val, arg2_name, arg2_val) \
616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_ASYNC_END, \
617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY, \
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val, arg2_name, arg2_val)
619c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Records a single FLOW_BEGIN event called "name" immediately, with 0, 1 or 2
622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// associated arguments. If the category is not enabled, then this
623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// does nothing.
624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - category and name strings must have application lifetime (statics or
625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   literals). They may not include " chars.
626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// - |id| is used to match the FLOW_BEGIN event with the FLOW_END event. FLOW
627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   events are considered to match if their category_group, name and id values
628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   all match. |id| must either be a pointer or an integer value up to 64 bits.
629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   If it's a pointer, the bits will be xored with a hash of the process ID so
630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//   that the same pointer on two different processes will not collide.
631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// FLOW events are different from ASYNC events in how they are drawn by the
632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// tracing UI. A FLOW defines asynchronous data flow, such as posting a task
633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// (FLOW_BEGIN) and later executing that task (FLOW_END). Expect FLOWs to be
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// drawn as lines or arrows from FLOW_BEGIN scopes to FLOW_END scopes. Similar
635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// to ASYNC, a FLOW can consist of multiple phases. The first phase is defined
636c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// by the FLOW_BEGIN calls. Additional phases can be defined using the FLOW_STEP
637c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// macros. When the operation completes, call FLOW_END. An async operation can
638c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// span threads and processes, but all events in that operation must use the
639c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// same |name| and |id|. Each event can have its own args.
640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_FLOW_BEGIN0(category_group, name, id) \
641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
642c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE)
643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_FLOW_BEGIN1(category_group, name, id, arg1_name, arg1_val) \
644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_FLOW_BEGIN2(category_group, name, id, arg1_name, arg1_val, \
647c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg2_name, arg2_val) \
648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
649c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, \
650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val, arg2_name, arg2_val)
651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_FLOW_BEGIN0(category_group, name, id) \
652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY)
654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_FLOW_BEGIN1(category_group, name, id, arg1_name, \
655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_val) \
656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
657c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY, \
658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val)
659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_FLOW_BEGIN2(category_group, name, id, arg1_name, \
660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_val, arg2_name, arg2_val) \
661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_BEGIN, \
662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY, \
663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val, arg2_name, arg2_val)
664c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Records a single FLOW_STEP event for |step| immediately. If the category
666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// is not enabled, then this does nothing. The |name| and |id| must match the
667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// FLOW_BEGIN event above. The |step| param identifies this step within the
668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// async event. This should be called at the beginning of the next phase of an
669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// asynchronous operation.
670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_FLOW_STEP0(category_group, name, id, step) \
671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step)
673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_FLOW_STEP1(category_group, name, id, step, \
674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val) \
675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
676c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, "step", step, \
677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val)
678c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_FLOW_STEP0(category_group, name, id, step) \
679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY, "step", step)
681c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_FLOW_STEP1(category_group, name, id, step, \
682c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val) \
683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_STEP, \
684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY, "step", step, \
685c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val)
686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Records a single FLOW_END event for "name" immediately. If the category
688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// is not enabled, then this does nothing.
689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_FLOW_END0(category_group, name, id) \
690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE)
692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_FLOW_END1(category_group, name, id, arg1_name, arg1_val) \
693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, arg1_name, arg1_val)
695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_FLOW_END2(category_group, name, id, arg1_name, arg1_val, \
696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg2_name, arg2_val) \
697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_NONE, \
699c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val, arg2_name, arg2_val)
700c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_FLOW_END0(category_group, name, id) \
701c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
702c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY)
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_FLOW_END1(category_group, name, id, arg1_name, \
704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_val) \
705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY, \
707c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val)
708c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_COPY_FLOW_END2(category_group, name, id, arg1_name, \
709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_val, arg2_name, arg2_val) \
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_FLOW_END, \
711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, TRACE_EVENT_FLAG_COPY, \
712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        arg1_name, arg1_val, arg2_name, arg2_val)
713c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
714ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// Macros to track the life time and value of arbitrary client objects.
715c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// See also TraceTrackableObject.
716c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group, name, id) \
717c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_CREATE_OBJECT, \
718c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_ID_DONT_MANGLE(id), TRACE_EVENT_FLAG_NONE)
719c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
720c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group, name, id, snapshot) \
721c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_SNAPSHOT_OBJECT, \
722c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_ID_DONT_MANGLE(id), TRACE_EVENT_FLAG_NONE,\
723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        "snapshot", snapshot)
724c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
725c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group, name, id) \
726c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_ADD_WITH_ID(TRACE_EVENT_PHASE_DELETE_OBJECT, \
727c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, TRACE_ID_DONT_MANGLE(id), TRACE_EVENT_FLAG_NONE)
728c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE() \
7305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UNLIKELY(*INTERNAL_TRACE_EVENT_UID(category_group_enabled) & \
7315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        (base::debug::TraceLog::ENABLED_FOR_RECORDING | \
7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         base::debug::TraceLog::ENABLED_FOR_EVENT_CALLBACK))
733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
73490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Macro to efficiently determine if a given category group is enabled.
73590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#define TRACE_EVENT_CATEGORY_GROUP_ENABLED(category_group, ret) \
73690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    do { \
73790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
73990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        *ret = true; \
74090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      } else { \
74190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        *ret = false; \
74290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      } \
74390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    } while (0)
74490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
745868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Macro to efficiently determine, through polling, if a new trace has begun.
746868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define TRACE_EVENT_IS_NEW_TRACE(ret) \
747868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    do { \
748868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      static int INTERNAL_TRACE_EVENT_UID(lastRecordingNumber) = 0; \
749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      int num_traces_recorded = TRACE_EVENT_API_GET_NUM_TRACES_RECORDED(); \
750868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (num_traces_recorded != -1 && \
751868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          num_traces_recorded != \
752868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          INTERNAL_TRACE_EVENT_UID(lastRecordingNumber)) { \
753868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        INTERNAL_TRACE_EVENT_UID(lastRecordingNumber) = \
754868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            num_traces_recorded; \
755868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        *ret = true; \
756868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      } else { \
757868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        *ret = false; \
758868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      } \
759868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    } while (0)
760868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Implementation specific tracing API definitions.
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get a pointer to the enabled state of the given trace category. Only
765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// long-lived literal strings should be given as the category group. The
766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// returned pointer can be held permanently in a local static for example. If
767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the unsigned char is non-zero, tracing is enabled. If tracing is enabled,
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TRACE_EVENT_API_ADD_TRACE_EVENT can be called. It's OK if tracing is disabled
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// between the load of the tracing state and the call to
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TRACE_EVENT_API_ADD_TRACE_EVENT, because this flag only provides an early out
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for best performance when tracing is disabled.
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// const unsigned char*
773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//     TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(const char* category_group)
774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED \
775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    base::debug::TraceLog::GetCategoryGroupEnabled
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
777868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Get the number of times traces have been recorded. This is used to implement
778868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// the TRACE_EVENT_IS_NEW_TRACE facility.
779868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// unsigned int TRACE_EVENT_API_GET_NUM_TRACES_RECORDED()
780868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define TRACE_EVENT_API_GET_NUM_TRACES_RECORDED \
781868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::debug::TraceLog::GetInstance()->GetNumTracesRecorded
782868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Add a trace event to the platform tracing system.
7848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// base::debug::TraceEventHandle TRACE_EVENT_API_ADD_TRACE_EVENT(
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                    char phase,
786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//                    const unsigned char* category_group_enabled,
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                    const char* name,
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                    unsigned long long id,
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                    int num_args,
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                    const char** arg_names,
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                    const unsigned char* arg_types,
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                    const unsigned long long* arg_values,
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                    unsigned char flags)
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TRACE_EVENT_API_ADD_TRACE_EVENT \
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::debug::TraceLog::GetInstance()->AddTraceEvent
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Add a trace event to the platform tracing system.
7988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// base::debug::TraceEventHandle TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_TIMESTAMP(
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//                    char phase,
800c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//                    const unsigned char* category_group_enabled,
8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//                    const char* name,
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//                    unsigned long long id,
8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//                    int thread_id,
8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//                    const TimeTicks& timestamp,
8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//                    int num_args,
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//                    const char** arg_names,
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//                    const unsigned char* arg_types,
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//                    const unsigned long long* arg_values,
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//                    unsigned char flags)
8102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP \
8112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::debug::TraceLog::GetInstance()->AddTraceEventWithThreadIdAndTimestamp
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Set the duration field of a COMPLETE trace event.
8148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// void TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
815f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//     const unsigned char* category_group_enabled,
816f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)//     const char* name,
8178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)//     base::debug::TraceEventHandle id)
8188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#define TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION \
8198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::debug::TraceLog::GetInstance()->UpdateTraceEventDuration
8208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Defines atomic operations used internally by the tracing system.
8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TRACE_EVENT_API_ATOMIC_WORD base::subtle::AtomicWord
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TRACE_EVENT_API_ATOMIC_LOAD(var) base::subtle::NoBarrier_Load(&(var))
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TRACE_EVENT_API_ATOMIC_STORE(var, value) \
8252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::subtle::NoBarrier_Store(&(var), (value))
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
827c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Defines visibility for classes in trace_event.h
8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TRACE_EVENT_API_CLASS_EXPORT BASE_EXPORT
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The thread buckets for the sampling profiler.
8317dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTRACE_EVENT_API_CLASS_EXPORT extern \
8327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TRACE_EVENT_API_ATOMIC_WORD g_trace_state[3];
8337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define TRACE_EVENT_API_THREAD_BUCKET(thread_bucket)                           \
8357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    g_trace_state[thread_bucket]
8367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
839c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Implementation detail: trace event macros create temporary variables
840c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// to keep instrumentation overhead low. These macros give each temporary
841ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// variable a unique name based on the line number to prevent name collisions.
842c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define INTERNAL_TRACE_EVENT_UID3(a,b) \
843c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    trace_event_unique_##a##b
844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define INTERNAL_TRACE_EVENT_UID2(a,b) \
845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_UID3(a,b)
846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define INTERNAL_TRACE_EVENT_UID(name_prefix) \
847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_UID2(name_prefix, __LINE__)
848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Implementation detail: internal macro to create static category.
850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// No barriers are needed, because this code is designed to operate safely
851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// even when the unsigned char* points to garbage data (which may be the case
852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// on processors without cache coherency).
8538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES( \
8548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    category_group, atomic, category_group_enabled) \
8558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    category_group_enabled = \
856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        reinterpret_cast<const unsigned char*>(TRACE_EVENT_API_ATOMIC_LOAD( \
8578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            atomic)); \
8585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (UNLIKELY(!category_group_enabled)) { \
8598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      category_group_enabled = \
860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); \
8618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      TRACE_EVENT_API_ATOMIC_STORE(atomic, \
862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>( \
8638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)              category_group_enabled)); \
864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
8668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#define INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group) \
8678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    static TRACE_EVENT_API_ATOMIC_WORD INTERNAL_TRACE_EVENT_UID(atomic) = 0; \
8688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const unsigned char* INTERNAL_TRACE_EVENT_UID(category_group_enabled); \
8698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO_CUSTOM_VARIABLES(category_group, \
8708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        INTERNAL_TRACE_EVENT_UID(atomic), \
8718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        INTERNAL_TRACE_EVENT_UID(category_group_enabled));
8728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Implementation detail: internal macro to create static category and add
874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// event if the category is enabled.
875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define INTERNAL_TRACE_EVENT_ADD(phase, category_group, name, flags, ...) \
876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    do { \
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
8785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        trace_event_internal::AddTraceEvent( \
8808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, \
881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            trace_event_internal::kNoEventId, flags, ##__VA_ARGS__); \
882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } \
883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } while (0)
884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Implementation detail: internal macro to create static category and add begin
886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// event if the category is enabled. Also adds the end event when the scope
887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// ends.
888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, ...) \
889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
8908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    trace_event_internal::ScopedTracer INTERNAL_TRACE_EVENT_UID(tracer); \
8915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
8928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      base::debug::TraceEventHandle h = trace_event_internal::AddTraceEvent( \
8938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          TRACE_EVENT_PHASE_COMPLETE, \
8948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)          INTERNAL_TRACE_EVENT_UID(category_group_enabled), \
895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          name, trace_event_internal::kNoEventId, \
896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          TRACE_EVENT_FLAG_NONE, ##__VA_ARGS__); \
8978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      INTERNAL_TRACE_EVENT_UID(tracer).Initialize( \
898f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          INTERNAL_TRACE_EVENT_UID(category_group_enabled), name, h); \
899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Implementation detail: internal macro to create static category and add
902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// event if the category is enabled.
903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define INTERNAL_TRACE_EVENT_ADD_WITH_ID(phase, category_group, name, id, \
904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         flags, ...) \
905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    do { \
906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
9075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        unsigned char trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \
909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        trace_event_internal::TraceID trace_event_trace_id( \
910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            id, &trace_event_flags); \
911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        trace_event_internal::AddTraceEvent( \
9128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), \
913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            name, trace_event_trace_id.data(), trace_event_flags, \
914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            ##__VA_ARGS__); \
915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } \
916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } while (0)
917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Implementation detail: internal macro to create static category and add
919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// event if the category is enabled.
920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP(phase, \
921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        category_group, name, id, thread_id, timestamp, flags, ...) \
922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    do { \
923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category_group); \
9245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (INTERNAL_TRACE_EVENT_CATEGORY_GROUP_ENABLED_FOR_RECORDING_MODE()) { \
925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        unsigned char trace_event_flags = flags | TRACE_EVENT_FLAG_HAS_ID; \
926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        trace_event_internal::TraceID trace_event_trace_id( \
927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            id, &trace_event_flags); \
928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        trace_event_internal::AddTraceEventWithThreadIdAndTimestamp( \
9298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            phase, INTERNAL_TRACE_EVENT_UID(category_group_enabled), \
930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            name, trace_event_trace_id.data(), \
931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            thread_id, base::TimeTicks::FromInternalValue(timestamp), \
932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            trace_event_flags, ##__VA_ARGS__); \
933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      } \
934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    } while (0)
935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Notes regarding the following definitions:
937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// New values can be added and propagated to third party libraries, but existing
938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// definitions must never be changed, because third party libraries may use old
939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// definitions.
940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Phase indicates the nature of an event entry. E.g. part of a begin/end pair.
942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_PHASE_BEGIN    ('B')
943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_PHASE_END      ('E')
9448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#define TRACE_EVENT_PHASE_COMPLETE ('X')
945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_PHASE_INSTANT  ('i')
946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_PHASE_ASYNC_BEGIN ('S')
9471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#define TRACE_EVENT_PHASE_ASYNC_STEP_INTO  ('T')
9481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#define TRACE_EVENT_PHASE_ASYNC_STEP_PAST  ('p')
949c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_PHASE_ASYNC_END   ('F')
950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_PHASE_FLOW_BEGIN ('s')
951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_PHASE_FLOW_STEP  ('t')
952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_PHASE_FLOW_END   ('f')
953c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_PHASE_METADATA ('M')
954c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_PHASE_COUNTER  ('C')
955c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_PHASE_SAMPLE  ('P')
956c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_PHASE_CREATE_OBJECT ('N')
957c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_PHASE_SNAPSHOT_OBJECT ('O')
958c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_PHASE_DELETE_OBJECT ('D')
959c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
960c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Flags for changing the behavior of TRACE_EVENT_API_ADD_TRACE_EVENT.
961c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_FLAG_NONE         (static_cast<unsigned char>(0))
962c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_FLAG_COPY         (static_cast<unsigned char>(1 << 0))
963c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_FLAG_HAS_ID       (static_cast<unsigned char>(1 << 1))
964c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_FLAG_MANGLE_ID    (static_cast<unsigned char>(1 << 2))
965c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_FLAG_SCOPE_OFFSET (static_cast<unsigned char>(1 << 3))
966c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
967c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_FLAG_SCOPE_MASK   (static_cast<unsigned char>( \
968c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT_FLAG_SCOPE_OFFSET | (TRACE_EVENT_FLAG_SCOPE_OFFSET << 1)))
969c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
970c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Type values for identifying types in the TraceValue union.
971c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_VALUE_TYPE_BOOL         (static_cast<unsigned char>(1))
972c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_VALUE_TYPE_UINT         (static_cast<unsigned char>(2))
973c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_VALUE_TYPE_INT          (static_cast<unsigned char>(3))
974c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_VALUE_TYPE_DOUBLE       (static_cast<unsigned char>(4))
975c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_VALUE_TYPE_POINTER      (static_cast<unsigned char>(5))
976c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_VALUE_TYPE_STRING       (static_cast<unsigned char>(6))
977c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_VALUE_TYPE_COPY_STRING  (static_cast<unsigned char>(7))
978c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_VALUE_TYPE_CONVERTABLE  (static_cast<unsigned char>(8))
979c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
980c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Enum reflecting the scope of an INSTANT event. Must fit within
981c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TRACE_EVENT_FLAG_SCOPE_MASK.
982c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_SCOPE_GLOBAL  (static_cast<unsigned char>(0 << 3))
983c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_SCOPE_PROCESS (static_cast<unsigned char>(1 << 3))
984c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_SCOPE_THREAD  (static_cast<unsigned char>(2 << 3))
985c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
986c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_SCOPE_NAME_GLOBAL  ('g')
987c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_SCOPE_NAME_PROCESS ('p')
988c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_SCOPE_NAME_THREAD  ('t')
989c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
990c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace trace_event_internal {
991c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
992c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Specify these values when the corresponding argument of AddTraceEvent is not
993c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// used.
994c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kZeroNumArgs = 0;
995c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const unsigned long long kNoEventId = 0;
996c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
997c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TraceID encapsulates an ID that can either be an integer or pointer. Pointers
998c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// are by default mangled with the Process ID so that they are unlikely to
999c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// collide when the same pointer is used on different processes.
1000c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TraceID {
1001c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
1002c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  class DontMangle {
1003c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   public:
1004d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    explicit DontMangle(const void* id)
1005c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        : data_(static_cast<unsigned long long>(
1006c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              reinterpret_cast<unsigned long>(id))) {}
1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit DontMangle(unsigned long long id) : data_(id) {}
1008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit DontMangle(unsigned long id) : data_(id) {}
1009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit DontMangle(unsigned int id) : data_(id) {}
1010c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit DontMangle(unsigned short id) : data_(id) {}
1011c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit DontMangle(unsigned char id) : data_(id) {}
1012c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit DontMangle(long long id)
1013c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        : data_(static_cast<unsigned long long>(id)) {}
1014c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit DontMangle(long id)
1015c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        : data_(static_cast<unsigned long long>(id)) {}
1016c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit DontMangle(int id)
1017c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        : data_(static_cast<unsigned long long>(id)) {}
1018c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit DontMangle(short id)
1019c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        : data_(static_cast<unsigned long long>(id)) {}
1020c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit DontMangle(signed char id)
1021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        : data_(static_cast<unsigned long long>(id)) {}
1022c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned long long data() const { return data_; }
1023c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   private:
1024c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned long long data_;
1025c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
1026c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1027c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  class ForceMangle {
1028c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   public:
1029c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit ForceMangle(unsigned long long id) : data_(id) {}
1030c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit ForceMangle(unsigned long id) : data_(id) {}
1031c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit ForceMangle(unsigned int id) : data_(id) {}
1032c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit ForceMangle(unsigned short id) : data_(id) {}
1033c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit ForceMangle(unsigned char id) : data_(id) {}
1034c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit ForceMangle(long long id)
1035c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        : data_(static_cast<unsigned long long>(id)) {}
1036c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit ForceMangle(long id)
1037c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        : data_(static_cast<unsigned long long>(id)) {}
1038c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit ForceMangle(int id)
1039c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        : data_(static_cast<unsigned long long>(id)) {}
1040c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit ForceMangle(short id)
1041c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        : data_(static_cast<unsigned long long>(id)) {}
1042c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    explicit ForceMangle(signed char id)
1043c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        : data_(static_cast<unsigned long long>(id)) {}
1044c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned long long data() const { return data_; }
1045c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)   private:
1046c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned long long data_;
1047c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
1048c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1049c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceID(const void* id, unsigned char* flags)
1050c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : data_(static_cast<unsigned long long>(
1051c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)              reinterpret_cast<unsigned long>(id))) {
1052c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
1053c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1054c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceID(ForceMangle id, unsigned char* flags) : data_(id.data()) {
1055c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *flags |= TRACE_EVENT_FLAG_MANGLE_ID;
1056c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1057c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceID(DontMangle id, unsigned char* flags) : data_(id.data()) {
1058c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1059c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceID(unsigned long long id, unsigned char* flags)
1060c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : data_(id) { (void)flags; }
1061c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceID(unsigned long id, unsigned char* flags)
1062c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : data_(id) { (void)flags; }
1063c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceID(unsigned int id, unsigned char* flags)
1064c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : data_(id) { (void)flags; }
1065c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceID(unsigned short id, unsigned char* flags)
1066c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : data_(id) { (void)flags; }
1067c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceID(unsigned char id, unsigned char* flags)
1068c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : data_(id) { (void)flags; }
1069c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceID(long long id, unsigned char* flags)
1070c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : data_(static_cast<unsigned long long>(id)) { (void)flags; }
1071c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceID(long id, unsigned char* flags)
1072c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : data_(static_cast<unsigned long long>(id)) { (void)flags; }
1073c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceID(int id, unsigned char* flags)
1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : data_(static_cast<unsigned long long>(id)) { (void)flags; }
1075c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceID(short id, unsigned char* flags)
1076c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : data_(static_cast<unsigned long long>(id)) { (void)flags; }
1077c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceID(signed char id, unsigned char* flags)
1078c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : data_(static_cast<unsigned long long>(id)) { (void)flags; }
1079c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1080c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned long long data() const { return data_; }
1081c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1082c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
1083c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned long long data_;
1084c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
1085c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1086c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Simple union to store various types as unsigned long long.
1087c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)union TraceValueUnion {
1088c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool as_bool;
1089c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned long long as_uint;
1090c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  long long as_int;
1091c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  double as_double;
1092c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const void* as_pointer;
1093c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const char* as_string;
1094c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
1095c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1096c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Simple container for const char* that should be copied instead of retained.
1097c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TraceStringWithCopy {
1098c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
1099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit TraceStringWithCopy(const char* str) : str_(str) {}
1100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const char* str() const { return str_; }
1101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
1102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const char* str_;
1103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
1104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Define SetTraceValue for each allowed type. It stores the type and
1106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// value in the return arguments. This allows this API to avoid declaring any
1107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// structures so that it is portable to third_party libraries.
1108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define INTERNAL_DECLARE_SET_TRACE_VALUE(actual_type, \
1109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                         arg_expression, \
1110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         union_member, \
1111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                         value_type_id) \
1112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static inline void SetTraceValue( \
1113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        actual_type arg, \
1114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        unsigned char* type, \
1115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        unsigned long long* value) { \
1116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TraceValueUnion type_value; \
1117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      type_value.union_member = arg_expression; \
1118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *type = value_type_id; \
1119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *value = type_value.as_uint; \
1120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Simpler form for int types that can be safely casted.
1122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define INTERNAL_DECLARE_SET_TRACE_VALUE_INT(actual_type, \
1123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                             value_type_id) \
1124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    static inline void SetTraceValue( \
1125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        actual_type arg, \
1126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        unsigned char* type, \
1127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        unsigned long long* value) { \
1128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *type = value_type_id; \
1129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      *value = static_cast<unsigned long long>(arg); \
1130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
1131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long long, TRACE_VALUE_TYPE_UINT)
1133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned long, TRACE_VALUE_TYPE_UINT)
1134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned int, TRACE_VALUE_TYPE_UINT)
1135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned short, TRACE_VALUE_TYPE_UINT)
1136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE_INT(unsigned char, TRACE_VALUE_TYPE_UINT)
1137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long long, TRACE_VALUE_TYPE_INT)
1138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE_INT(long, TRACE_VALUE_TYPE_INT)
1139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE_INT(int, TRACE_VALUE_TYPE_INT)
1140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE_INT(short, TRACE_VALUE_TYPE_INT)
1141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE_INT(signed char, TRACE_VALUE_TYPE_INT)
1142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE(bool, arg, as_bool, TRACE_VALUE_TYPE_BOOL)
1143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE(double, arg, as_double,
1144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                 TRACE_VALUE_TYPE_DOUBLE)
1145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE(const void*, arg, as_pointer,
1146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 TRACE_VALUE_TYPE_POINTER)
1147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE(const char*, arg, as_string,
1148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 TRACE_VALUE_TYPE_STRING)
1149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)INTERNAL_DECLARE_SET_TRACE_VALUE(const TraceStringWithCopy&, arg.str(),
1150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                 as_string, TRACE_VALUE_TYPE_COPY_STRING)
1151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#undef INTERNAL_DECLARE_SET_TRACE_VALUE
1153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#undef INTERNAL_DECLARE_SET_TRACE_VALUE_INT
1154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// std::string version of SetTraceValue so that trace arguments can be strings.
1156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static inline void SetTraceValue(const std::string& arg,
1157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 unsigned char* type,
1158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                 unsigned long long* value) {
1159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceValueUnion type_value;
1160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  type_value.as_string = arg.c_str();
1161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *type = TRACE_VALUE_TYPE_COPY_STRING;
1162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *value = type_value.as_uint;
1163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
116523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// base::Time and base::TimeTicks version of SetTraceValue to make it easier to
116623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// trace these types.
116723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)static inline void SetTraceValue(const base::Time arg,
116823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                 unsigned char* type,
116923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                 unsigned long long* value) {
117023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  *type = TRACE_VALUE_TYPE_INT;
117123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  *value = arg.ToInternalValue();
117223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
117323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
117423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)static inline void SetTraceValue(const base::TimeTicks arg,
117523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                 unsigned char* type,
117623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                                 unsigned long long* value) {
117723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  *type = TRACE_VALUE_TYPE_INT;
117823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  *value = arg.ToInternalValue();
117923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
118023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
1181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// These AddTraceEvent and AddTraceEventWithThreadIdAndTimestamp template
1182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// functions are defined here instead of in the macro, because the arg_values
1183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// could be temporary objects, such as std::string. In order to store
1184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// pointers to the internal c_str and pass through to the tracing API,
1185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the arg_values must live throughout these procedures.
1186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
11878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)static inline base::debug::TraceEventHandle
11888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)AddTraceEventWithThreadIdAndTimestamp(
1189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    char phase,
1190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const unsigned char* category_group_enabled,
1191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* name,
1192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned long long id,
1193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int thread_id,
1194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::TimeTicks& timestamp,
1195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned char flags,
1196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* arg1_name,
11974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const scoped_refptr<base::debug::ConvertableToTraceFormat>& arg1_val) {
1198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const int num_args = 1;
1199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned char arg_types[1] = { TRACE_VALUE_TYPE_CONVERTABLE };
12008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
1201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      phase, category_group_enabled, name, id, thread_id, timestamp,
12024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      num_args, &arg1_name, arg_types, NULL, &arg1_val, flags);
1203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1205b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)template<class ARG1_TYPE>
12068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)static inline base::debug::TraceEventHandle
12078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)AddTraceEventWithThreadIdAndTimestamp(
1208b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    char phase,
1209b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const unsigned char* category_group_enabled,
1210b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const char* name,
1211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    unsigned long long id,
1212b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    int thread_id,
1213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const base::TimeTicks& timestamp,
1214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    unsigned char flags,
1215b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const char* arg1_name,
12164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const ARG1_TYPE& arg1_val,
1217b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const char* arg2_name,
12184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const scoped_refptr<base::debug::ConvertableToTraceFormat>& arg2_val) {
1219b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  const int num_args = 2;
1220b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  const char* arg_names[2] = { arg1_name, arg2_name };
1221b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1222b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  unsigned char arg_types[2];
1223b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  unsigned long long arg_values[2];
1224b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
1225b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  arg_types[1] = TRACE_VALUE_TYPE_CONVERTABLE;
1226b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
12274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_refptr<base::debug::ConvertableToTraceFormat> convertable_values[2];
12284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  convertable_values[1] = arg2_val;
1229b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
12308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
1231b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      phase, category_group_enabled, name, id, thread_id, timestamp,
1232b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      num_args, arg_names, arg_types, arg_values, convertable_values, flags);
1233b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
1234b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1235b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)template<class ARG2_TYPE>
12368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)static inline base::debug::TraceEventHandle
12378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)AddTraceEventWithThreadIdAndTimestamp(
1238b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    char phase,
1239b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const unsigned char* category_group_enabled,
1240b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const char* name,
1241b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    unsigned long long id,
1242b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    int thread_id,
1243b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const base::TimeTicks& timestamp,
1244b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    unsigned char flags,
1245b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const char* arg1_name,
12464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const scoped_refptr<base::debug::ConvertableToTraceFormat>& arg1_val,
1247b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    const char* arg2_name,
12484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const ARG2_TYPE& arg2_val) {
1249b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  const int num_args = 2;
1250b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  const char* arg_names[2] = { arg1_name, arg2_name };
1251b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
1252b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  unsigned char arg_types[2];
1253b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  unsigned long long arg_values[2];
1254b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  arg_types[0] = TRACE_VALUE_TYPE_CONVERTABLE;
1255b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  arg_values[0] = 0;
1256b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]);
1257b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
12584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_refptr<base::debug::ConvertableToTraceFormat> convertable_values[2];
12594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  convertable_values[0] = arg1_val;
1260b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
12618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
1262b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      phase, category_group_enabled, name, id, thread_id, timestamp,
1263b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      num_args, arg_names, arg_types, arg_values, convertable_values, flags);
1264b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}
1265b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
12668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)static inline base::debug::TraceEventHandle
12678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)AddTraceEventWithThreadIdAndTimestamp(
1268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    char phase,
1269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const unsigned char* category_group_enabled,
1270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* name,
1271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned long long id,
1272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int thread_id,
1273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::TimeTicks& timestamp,
1274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned char flags,
1275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* arg1_name,
12764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const scoped_refptr<base::debug::ConvertableToTraceFormat>& arg1_val,
1277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* arg2_name,
12784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const scoped_refptr<base::debug::ConvertableToTraceFormat>& arg2_val) {
1279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const int num_args = 2;
1280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const char* arg_names[2] = { arg1_name, arg2_name };
1281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned char arg_types[2] =
1282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      { TRACE_VALUE_TYPE_CONVERTABLE, TRACE_VALUE_TYPE_CONVERTABLE };
12834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_refptr<base::debug::ConvertableToTraceFormat> convertable_values[2] =
12844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      { arg1_val, arg2_val };
1285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
1287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      phase, category_group_enabled, name, id, thread_id, timestamp,
1288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      num_args, arg_names, arg_types, NULL, convertable_values, flags);
1289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
12918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)static inline base::debug::TraceEventHandle
12928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)AddTraceEventWithThreadIdAndTimestamp(
1293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    char phase,
1294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const unsigned char* category_group_enabled,
1295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* name,
1296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned long long id,
1297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int thread_id,
1298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::TimeTicks& timestamp,
1299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned char flags) {
13008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
1301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      phase, category_group_enabled, name, id, thread_id, timestamp,
1302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      kZeroNumArgs, NULL, NULL, NULL, NULL, flags);
1303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
13058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)static inline base::debug::TraceEventHandle AddTraceEvent(
13068bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    char phase,
13078bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const unsigned char* category_group_enabled,
13088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const char* name,
13098bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    unsigned long long id,
13108bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    unsigned char flags) {
1311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
1312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
13138bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled,
13148bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                               name, id, thread_id, now, flags);
1315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<class ARG1_TYPE>
13188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)static inline base::debug::TraceEventHandle
13198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)AddTraceEventWithThreadIdAndTimestamp(
1320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    char phase,
1321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const unsigned char* category_group_enabled,
1322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* name,
1323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned long long id,
1324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int thread_id,
1325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::TimeTicks& timestamp,
1326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned char flags,
1327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* arg1_name,
1328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ARG1_TYPE& arg1_val) {
1329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const int num_args = 1;
1330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned char arg_types[1];
1331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned long long arg_values[1];
1332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
13338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
1334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      phase, category_group_enabled, name, id, thread_id, timestamp,
1335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      num_args, &arg1_name, arg_types, arg_values, NULL, flags);
1336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<class ARG1_TYPE>
13398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)static inline base::debug::TraceEventHandle AddTraceEvent(
13408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    char phase,
13418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const unsigned char* category_group_enabled,
13428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const char* name,
13438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    unsigned long long id,
13448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    unsigned char flags,
13458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const char* arg1_name,
13468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const ARG1_TYPE& arg1_val) {
1347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
1348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
13498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled,
13508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                               name, id, thread_id, now, flags,
13518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                               arg1_name, arg1_val);
1352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<class ARG1_TYPE, class ARG2_TYPE>
13558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)static inline base::debug::TraceEventHandle
13568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)AddTraceEventWithThreadIdAndTimestamp(
1357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    char phase,
1358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const unsigned char* category_group_enabled,
1359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* name,
1360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned long long id,
1361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int thread_id,
1362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::TimeTicks& timestamp,
1363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    unsigned char flags,
1364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* arg1_name,
1365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ARG1_TYPE& arg1_val,
1366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* arg2_name,
1367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const ARG2_TYPE& arg2_val) {
1368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const int num_args = 2;
1369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const char* arg_names[2] = { arg1_name, arg2_name };
1370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned char arg_types[2];
1371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  unsigned long long arg_values[2];
1372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetTraceValue(arg1_val, &arg_types[0], &arg_values[0]);
1373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SetTraceValue(arg2_val, &arg_types[1], &arg_values[1]);
13748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(
1375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      phase, category_group_enabled, name, id, thread_id, timestamp,
1376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      num_args, arg_names, arg_types, arg_values, NULL, flags);
1377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<class ARG1_TYPE, class ARG2_TYPE>
13808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)static inline base::debug::TraceEventHandle AddTraceEvent(
13818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    char phase,
13828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const unsigned char* category_group_enabled,
13838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const char* name,
13848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    unsigned long long id,
13858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    unsigned char flags,
13868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const char* arg1_name,
13878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const ARG1_TYPE& arg1_val,
13888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const char* arg2_name,
13898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const ARG2_TYPE& arg2_val) {
1390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int thread_id = static_cast<int>(base::PlatformThread::CurrentId());
1391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::TimeTicks now = base::TimeTicks::NowFromSystemTraceTime();
13928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return AddTraceEventWithThreadIdAndTimestamp(phase, category_group_enabled,
13938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                               name, id, thread_id, now, flags,
13948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                               arg1_name, arg1_val,
13958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                               arg2_name, arg2_val);
1396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
13988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Used by TRACE_EVENTx macros. Do not use directly.
13998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class TRACE_EVENT_API_CLASS_EXPORT ScopedTracer {
1400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
1401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Note: members of data_ intentionally left uninitialized. See Initialize.
14028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ScopedTracer() : p_data_(NULL) {}
14038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
14048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ~ScopedTracer() {
14058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (p_data_ && *data_.category_group_enabled)
1406f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      TRACE_EVENT_API_UPDATE_TRACE_EVENT_DURATION(
1407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          data_.category_group_enabled, data_.name, data_.event_handle);
1408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Initialize(const unsigned char* category_group_enabled,
1411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                  const char* name,
14128bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                  base::debug::TraceEventHandle event_handle) {
1413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    data_.category_group_enabled = category_group_enabled;
1414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    data_.name = name;
14158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    data_.event_handle = event_handle;
1416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    p_data_ = &data_;
1417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
1420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This Data struct workaround is to avoid initializing all the members
1421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // in Data during construction of this object, since this object is always
1422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // constructed, even when tracing is disabled. If the members of Data were
1423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // members of this class instead, compiler warnings occur about potential
1424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // uninitialized accesses.
1425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  struct Data {
1426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const unsigned char* category_group_enabled;
1427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const char* name;
14288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::debug::TraceEventHandle event_handle;
1429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
1430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Data* p_data_;
1431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Data data_;
1432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
1433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Used by TRACE_EVENT_BINARY_EFFICIENTx macro. Do not use directly.
14358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class TRACE_EVENT_API_CLASS_EXPORT ScopedTraceBinaryEfficient {
1436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
14378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ScopedTraceBinaryEfficient(const char* category_group, const char* name);
14388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  ~ScopedTraceBinaryEfficient();
1439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
1441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const unsigned char* category_group_enabled_;
1442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const char* name_;
14438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::debug::TraceEventHandle event_handle_;
1444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
1445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// This macro generates less code then TRACE_EVENT0 but is also
1447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// slower to execute when tracing is off. It should generally only be
1448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// used with code that is seldom executed or conditionally executed
1449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// when debugging.
14508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// For now the category_group must be "gpu".
1451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define TRACE_EVENT_BINARY_EFFICIENT0(category_group, name) \
14528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    trace_event_internal::ScopedTraceBinaryEfficient \
14538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        INTERNAL_TRACE_EVENT_UID(scoped_trace)(category_group, name);
1454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
14557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// TraceEventSamplingStateScope records the current sampling state
14567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// and sets a new sampling state. When the scope exists, it restores
14577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// the sampling state having recorded.
14587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochtemplate<size_t BucketNumber>
14597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass TraceEventSamplingStateScope {
14607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public:
14617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TraceEventSamplingStateScope(const char* category_and_name) {
14627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    previous_state_ = TraceEventSamplingStateScope<BucketNumber>::Current();
14637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TraceEventSamplingStateScope<BucketNumber>::Set(category_and_name);
14647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
14657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
14667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ~TraceEventSamplingStateScope() {
14677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TraceEventSamplingStateScope<BucketNumber>::Set(previous_state_);
14687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
14697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
14707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static inline const char* Current() {
14717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return reinterpret_cast<const char*>(TRACE_EVENT_API_ATOMIC_LOAD(
14727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      g_trace_state[BucketNumber]));
14737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
14747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
14757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static inline void Set(const char* category_and_name) {
14767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    TRACE_EVENT_API_ATOMIC_STORE(
14777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      g_trace_state[BucketNumber],
14787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      reinterpret_cast<TRACE_EVENT_API_ATOMIC_WORD>(
14797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        const_cast<char*>(category_and_name)));
14807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
14817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
14827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private:
14837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const char* previous_state_;
14847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
14857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace trace_event_internal
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace debug {
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename IDType> class TraceScopedTrackableObject {
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  TraceScopedTrackableObject(const char* category_group, const char* name,
1494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      IDType id)
1495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : category_group_(category_group),
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      name_(name),
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      id_(id) {
1498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT_OBJECT_CREATED_WITH_ID(category_group_, name_, id_);
1499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  template <typename ArgType> void snapshot(ArgType snapshot) {
1502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(category_group_, name_, id_, snapshot);
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~TraceScopedTrackableObject() {
1506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TRACE_EVENT_OBJECT_DELETED_WITH_ID(category_group_, name_, id_);
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const char* category_group_;
15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char* name_;
15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IDType id_;
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TraceScopedTrackableObject);
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace debug
15182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace base
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif /* BASE_DEBUG_TRACE_EVENT_H_ */
1521