minitrace.h
Go to the documentation of this file.
1 #ifndef MINITRACE_H
2 #define MINITRACE_H
3 
4 // Minitrace
5 //
6 // Copyright 2014 by Henrik RydgĂ„rd
7 // http://www.github.com/hrydgard/minitrace
8 // Released under the MIT license.
9 //
10 // Ultra-light dependency free library for performance tracing C/C++ applications.
11 // Produces traces compatible with Google Chrome's trace viewer.
12 // Simply open "about:tracing" in Chrome and load the produced JSON.
13 //
14 // This contains far less template magic than the original libraries from Chrome
15 // because this is meant to be usable from C.
16 //
17 // See README.md for a tutorial.
18 //
19 // The trace format is documented here:
20 // https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/edit
21 // More:
22 // http://www.altdevblogaday.com/2012/08/21/using-chrometracing-to-view-your-inline-profiling-data/
23 
24 #include <inttypes.h>
25 
26 #define MTR_ENABLED
27 
28 // If MTR_ENABLED is not defined, Minitrace does nothing and has near zero overhead.
29 // Preferably, set this flag in your build system. If you can't just uncomment this line.
30 // #define MTR_ENABLED
31 
32 // By default, will collect up to 1000000 events, then you must flush.
33 // It's recommended that you simply call mtr_flush on a background thread
34 // occasionally. It's safe...ish.
35 #define INTERNAL_MINITRACE_BUFFER_SIZE 1000000
36 
37 //#define MTR_ENABLED
38 
39 namespace minitrace {
40 
41 // Initializes Minitrace. Must be called very early during startup of your executable,
42 // before any MTR_ statements..
43 void mtr_init(const char *json_file);
44 
45 // Shuts down minitrace cleanly, flushing the trace buffer.
46 void mtr_shutdown();
47 
48 // Lets you enable and disable Minitrace at runtime.
49 // May cause strange discontinuities in the output.
50 // Minitrace is enabled on startup by default.
51 void mtr_start();
52 void mtr_stop();
53 
54 // Flushes the collected data to disk, clearing the buffer for new data.
55 void mtr_flush();
56 
57 // Returns the current time in seconds. Used internally by Minitrace. No caching.
58 int64_t mtr_time_usec();
59 
60 // Registers a handler that will flush the trace on Ctrl+C.
61 // Works on Linux and MacOSX, and in Win32 console applications.
63 
64 // Utility function that should rarely be used.
65 // If str is semi dynamic, store it permanently in a small pool so we don't need to malloc it.
66 // The pool fills up fast though and performance isn't great.
67 // Returns a fixed string if the pool is full.
68 const char *mtr_pool_string(const char *str);
69 
70 // Commented-out types will be supported in the future.
71 typedef enum {
73  MTR_ARG_TYPE_INT = 1, // I
74  // MTR_ARG_TYPE_FLOAT = 2, // TODO
75  // MTR_ARG_TYPE_DOUBLE = 3, // TODO
78  // MTR_ARG_TYPE_JSON_COPY = 10,
79 } mtr_arg_type;
80 
81 // TODO: Add support for more than one argument (metadata) per event
82 // Having more costs speed and memory.
83 #define MTR_MAX_ARGS 1
84 
85 // Only use the macros to call these.
86 void internal_mtr_raw_event(const char *category, const char *name, char ph, void *id);
87 void internal_mtr_raw_event_arg(const char *category, const char *name, char ph, void *id, mtr_arg_type arg_type, const char *arg_name, void *arg_value);
88 
89 #ifdef MTR_ENABLED
90 
91 // c - category. Can be filtered by in trace viewer (or at least that's the intention).
92 // A good use is to pass __FILE__, there are macros further below that will do it for you.
93 // n - name. Pass __FUNCTION__ in most cases, unless you are marking up parts of one.
94 
95 // Scopes. In C++, use MTR_SCOPE. In C, always match them within the same scope.
96 #define MTR_BEGIN(c, n) internal_mtr_raw_event(c, n, 'B', nullptr)
97 #define MTR_END(c, n) internal_mtr_raw_event(c, n, 'E', nullptr)
98 #define MTR_SCOPE(c, n) MTRScopedTrace ____mtr_scope(c, n)
99 #define MTR_SCOPE_LIMIT(c, n, l) MTRScopedTraceLimit ____mtr_scope(c, n, l)
100 
101 // Async events. Can span threads. ID identifies which events to connect in the view.
102 #define MTR_START(c, n, id) internal_mtr_raw_event(c, n, 'S', (void *)(id))
103 #define MTR_STEP(c, n, id, step) internal_mtr_raw_event_arg(c, n, 'T', (void *)(id), MTR_ARG_TYPE_STRING_CONST, "step", (void *)(step))
104 #define MTR_FINISH(c, n, id) internal_mtr_raw_event(c, n, 'F', (void *)(id))
105 
106 // Flow events. Like async events, but displayed in a more fancy way in the viewer.
107 #define MTR_FLOW_START(c, n, id) internal_mtr_raw_event(c, n, 's', (void *)(id))
108 #define MTR_FLOW_STEP(c, n, id, step) internal_mtr_raw_event_arg(c, n, 't', (void *)(id), MTR_ARG_TYPE_STRING_CONST, "step", (void *)(step))
109 #define MTR_FLOW_FINISH(c, n, id) internal_mtr_raw_event(c, n, 'f', (void *)(id))
110 
111 // The same macros, but with a single named argument which shows up as metadata in the viewer.
112 // _I for int.
113 // _C is for a const string arg.
114 // _S will copy the string, freeing on flush (expensive but sometimes necessary).
115 // but required if the string was generated dynamically.
116 
117 // Note that it's fine to match BEGIN_S with END and BEGIN with END_S, etc.
118 #define MTR_BEGIN_C(c, n, aname, astrval) internal_mtr_raw_event_arg(c, n, 'B', 0, MTR_ARG_TYPE_STRING_CONST, aname, (void *)(astrval))
119 #define MTR_END_C(c, n, aname, astrval) internal_mtr_raw_event_arg(c, n, 'E', 0, MTR_ARG_TYPE_STRING_CONST, aname, (void *)(astrval))
120 #define MTR_SCOPE_C(c, n, aname, astrval) MTRScopedTraceArg ____mtr_scope(c, n, MTR_ARG_TYPE_STRING_CONST, aname, (void *)(astrval))
121 
122 #define MTR_BEGIN_S(c, n, aname, astrval) internal_mtr_raw_event_arg(c, n, 'B', 0, MTR_ARG_TYPE_STRING_COPY, aname, (void *)(astrval))
123 #define MTR_END_S(c, n, aname, astrval) internal_mtr_raw_event_arg(c, n, 'E', 0, MTR_ARG_TYPE_STRING_COPY, aname, (void *)(astrval))
124 #define MTR_SCOPE_S(c, n, aname, astrval) MTRScopedTraceArg ____mtr_scope(c, n, MTR_ARG_TYPE_STRING_COPY, aname, (void *)(astrval))
125 
126 #define MTR_BEGIN_I(c, n, aname, aintval) internal_mtr_raw_event_arg(c, n, 'B', 0, MTR_ARG_TYPE_INT, aname, (void*)(intptr_t)(aintval))
127 #define MTR_END_I(c, n, aname, aintval) internal_mtr_raw_event_arg(c, n, 'E', 0, MTR_ARG_TYPE_INT, aname, (void*)(intptr_t)(aintval))
128 #define MTR_SCOPE_I(c, n, aname, aintval) MTRScopedTraceArg ____mtr_scope(c, n, MTR_ARG_TYPE_INT, aname, (void*)(intptr_t)(aintval))
129 
130 // Instant events. For things with no duration.
131 #define MTR_INSTANT(c, n) internal_mtr_raw_event(c, n, 'I', nullptr)
132 #define MTR_INSTANT_C(c, n, aname, astrval) internal_mtr_raw_event(c, n, 'I', 0, MTR_ARG_TYPE_STRING_CONST, aname, (void *)(astrval))
133 #define MTR_INSTANT_I(c, n, aname, aintval) internal_mtr_raw_event(c, n, 'I', 0, MTR_ARG_TYPE_INT, aname, (void *)(aintval))
134 
135 // Counters (can't do multi-value counters yet)
136 #define MTR_COUNTER(c, n, val) internal_mtr_raw_event_arg(c, n, 'C', 0, MTR_ARG_TYPE_INT, n, (void *)(intptr_t)(val))
137 
138 // Metadata. Call at the start preferably. Must be const strings.
139 
140 #define MTR_META_PROCESS_NAME(n) internal_mtr_raw_event_arg("", "process_name", 'M', 0, MTR_ARG_TYPE_STRING_COPY, "name", (void *)(n))
141 #define MTR_META_THREAD_NAME(n) internal_mtr_raw_event_arg("", "thread_name", 'M', 0, MTR_ARG_TYPE_STRING_COPY, "name", (void *)(n))
142 #define MTR_META_THREAD_SORT_INDEX(i) internal_mtr_raw_event_arg("", "thread_sort_index", 'M', 0, MTR_ARG_TYPE_INT, "sort_index", (void *)(i))
143 
144 #else
145 
146 #define MTR_BEGIN(c, n)
147 #define MTR_END(c, n)
148 #define MTR_SCOPE(c, n)
149 #define MTR_START(c, n, id)
150 #define MTR_STEP(c, n, id, step)
151 #define MTR_FINISH(c, n, id)
152 #define MTR_FLOW_START(c, n, id)
153 #define MTR_FLOW_STEP(c, n, id, step)
154 #define MTR_FLOW_FINISH(c, n, id)
155 #define MTR_INSTANT(c, n)
156 
157 #define MTR_BEGIN_C(c, n, aname, astrval)
158 #define MTR_END_C(c, n, aname, astrval)
159 #define MTR_SCOPE_C(c, n, aname, astrval)
160 
161 #define MTR_BEGIN_S(c, n, aname, astrval)
162 #define MTR_END_S(c, n, aname, astrval)
163 #define MTR_SCOPE_S(c, n, aname, astrval)
164 
165 #define MTR_BEGIN_I(c, n, aname, aintval)
166 #define MTR_END_I(c, n, aname, aintval)
167 #define MTR_SCOPE_I(c, n, aname, aintval)
168 
169 #define MTR_INSTANT(c, n)
170 #define MTR_INSTANT_C(c, n, aname, astrval)
171 #define MTR_INSTANT_I(c, n, aname, aintval)
172 
173 // Counters (can't do multi-value counters yet)
174 #define MTR_COUNTER(c, n, val)
175 
176 // Metadata. Call at the start preferably. Must be const strings.
177 
178 #define MTR_META_PROCESS_NAME(n)
179 
180 #define MTR_META_THREAD_NAME(n)
181 #define MTR_META_THREAD_SORT_INDEX(i)
182 
183 #endif
184 
185 // Shortcuts for simple function timing with automatic categories and names.
186 
187 #define MTR_BEGIN_FUNC() MTR_BEGIN(__FILE__, __FUNCTION__)
188 #define MTR_END_FUNC() MTR_END(__FILE__, __FUNCTION__)
189 #define MTR_SCOPE_FUNC() MTR_SCOPE(__FILE__, __FUNCTION__)
190 #define MTR_INSTANT_FUNC() MTR_INSTANT(__FILE__, __FUNCTION__)
191 #define MTR_SCOPE_FUNC_LIMIT_S(l) MTRScopedTraceLimit ____mtr_scope(__FILE__, __FUNCTION__, l)
192 #define MTR_SCOPE_FUNC_LIMIT_MS(l) MTRScopedTraceLimit ____mtr_scope(__FILE__, __FUNCTION__, 1)
193 
194 // Same, but with a single argument of the usual types.
195 #define MTR_BEGIN_FUNC_S(aname, arg) MTR_BEGIN_S(__FILE__, __FUNCTION__, aname, arg)
196 #define MTR_END_FUNC_S(aname, arg) MTR_END_S(__FILE__, __FUNCTION__, aname, arg)
197 #define MTR_SCOPE_FUNC_S(aname, arg) MTR_SCOPE_S(__FILE__, __FUNCTION__, aname, arg)
198 
199 #define MTR_BEGIN_FUNC_C(aname, arg) MTR_BEGIN_C(__FILE__, __FUNCTION__, aname, arg)
200 #define MTR_END_FUNC_C(aname, arg) MTR_END_C(__FILE__, __FUNCTION__, aname, arg)
201 #define MTR_SCOPE_FUNC_C(aname, arg) MTR_SCOPE_C(__FILE__, __FUNCTION__, aname, arg)
202 
203 #define MTR_BEGIN_FUNC_I(aname, arg) MTR_BEGIN_I(__FILE__, __FUNCTION__, aname, arg)
204 #define MTR_END_FUNC_I(aname, arg) MTR_END_I(__FILE__, __FUNCTION__, aname, arg)
205 #define MTR_SCOPE_FUNC_I(aname, arg) MTR_SCOPE_I(__FILE__, __FUNCTION__, aname, arg)
206 
207 
208 #ifdef MTR_ENABLED
209 // These are optimized to use X events (combined B and E). Much easier to do in C++ than in C.
211 public:
212  MTRScopedTrace(const char *category, const char *name)
213  : category_(category), name_(name) {
215  }
218  }
219 
220 private:
221  const char *category_;
222  const char *name_;
223  int64_t start_time_;
224 };
225 
226 // Only outputs a block if execution time exceeded the limit.
227 // TODO: This will effectively call mtr_time_usec twice at the end, which is bad.
229 public:
230  MTRScopedTraceLimit(const char *category, const char *name, double limit_s)
231  : category_(category), name_(name), limit_(limit_s) {
233  }
235  int64_t end_time = mtr_time_usec();
236  if (end_time - start_time_ >= limit_) {
238  }
239  }
240 
241 private:
242  const char *category_;
243  const char *name_;
244  double start_time_;
245  double limit_;
246 };
247 
249 public:
250  MTRScopedTraceArg(const char *category, const char *name, mtr_arg_type arg_type, const char *arg_name, void *arg_value)
251  : category_(category), name_(name) {
252  internal_mtr_raw_event_arg(category, name, 'B', 0, arg_type, arg_name, arg_value);
253  }
256  }
257 
258 private:
259  const char *category_;
260  const char *name_;
261 };
262 
263 #endif
264 
265 } //end namespace
266 
267 #endif
void mtr_shutdown()
Definition: minitrace.cpp:173
void mtr_register_sigint_handler()
Definition: minitrace.cpp:147
void mtr_init(const char *json_file)
Definition: minitrace.cpp:158
MTRScopedTraceLimit(const char *category, const char *name, double limit_s)
Definition: minitrace.h:230
const char * category_
Definition: minitrace.h:221
void mtr_stop()
Definition: minitrace.cpp:216
void internal_mtr_raw_event_arg(const char *category, const char *name, char ph, void *id, mtr_arg_type arg_type, const char *arg_name, void *arg_value)
Definition: minitrace.cpp:340
MTRScopedTraceArg(const char *category, const char *name, mtr_arg_type arg_type, const char *arg_name, void *arg_value)
Definition: minitrace.h:250
void mtr_start()
Definition: minitrace.cpp:209
int64_t mtr_time_usec()
Definition: minitrace.cpp:125
MTRScopedTrace(const char *category, const char *name)
Definition: minitrace.h:212
void internal_mtr_raw_event(const char *category, const char *name, char ph, void *id)
Definition: minitrace.cpp:303
const char * mtr_pool_string(const char *str)
Definition: minitrace.cpp:194
void mtr_flush()
Definition: minitrace.cpp:224


behaviortree_cpp
Author(s): Michele Colledanchise, Davide Faconti
autogenerated on Sat Feb 2 2019 04:01:53