libstdc++
profiler.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Copyright (C) 2009-2013 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
19 
20 // You should have received a copy of the GNU General Public License along
21 // with this library; see the file COPYING3. If not see
22 // <http://www.gnu.org/licenses/>.
23 
24 /** @file profile/impl/profiler.h
25  * @brief Interface of the profiling runtime library.
26  */
27 
28 // Written by Lixia Liu and Silvius Rus.
29 
30 #ifndef _GLIBCXX_PROFILE_PROFILER_H
31 #define _GLIBCXX_PROFILE_PROFILER_H 1
32 
33 #include <bits/c++config.h>
34 
35 // Mechanism to define data with inline linkage.
36 #define _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__type, __name) \
37  inline __type& \
38  __get_##__name() \
39  { \
40  static __type __name; \
41  return __name; \
42  }
43 #define _GLIBCXX_PROFILE_DEFINE_DATA(__type, __name, __initial_value...) \
44  inline __type& __get_##__name() { \
45  static __type __name(__initial_value); \
46  return __name; \
47  }
48 #define _GLIBCXX_PROFILE_DATA(__name) \
49  __get_##__name()
50 
51 namespace __gnu_profile
52 {
53  /** @brief Reentrance guard.
54  *
55  * Mechanism to protect all __gnu_profile operations against recursion,
56  * multithreaded and exception reentrance.
57  */
59  {
60  static bool
61  __get_in()
62  {
63  if (__inside() == true)
64  return false;
65  else
66  {
67  __inside() = true;
68  return true;
69  }
70  }
71 
72  static bool&
73  __inside()
74  {
75  static __thread bool _S_inside(false);
76  return _S_inside;
77  }
78 
79  __reentrance_guard() { }
80  ~__reentrance_guard() { __inside() = false; }
81  };
82 
83 #define _GLIBCXX_PROFILE_REENTRANCE_GUARD(__x...) \
84  { \
85  if (__gnu_profile::__reentrance_guard::__get_in()) \
86  { \
87  __gnu_profile::__reentrance_guard __get_out; \
88  __x; \
89  } \
90  }
91 
92  // Forward declarations of implementation functions.
93  // Don't use any __gnu_profile:: in user code.
94  // Instead, use the __profcxx... macros, which offer guarded access.
95  bool __turn_on();
96  bool __turn_off();
97  bool __is_invalid();
98  bool __is_on();
99  bool __is_off();
100  void __report(void);
101  void __trace_hashtable_size_resize(const void*, std::size_t, std::size_t);
102  void __trace_hashtable_size_destruct(const void*, std::size_t, std::size_t);
103  void __trace_hashtable_size_construct(const void*, std::size_t);
104  void __trace_vector_size_resize(const void*, std::size_t, std::size_t);
105  void __trace_vector_size_destruct(const void*, std::size_t, std::size_t);
106  void __trace_vector_size_construct(const void*, std::size_t);
107  void __trace_hash_func_destruct(const void*, std::size_t, std::size_t,
108  std::size_t);
109  void __trace_hash_func_construct(const void*);
110  void __trace_vector_to_list_destruct(const void*);
111  void __trace_vector_to_list_construct(const void*);
112  void __trace_vector_to_list_insert(const void*, std::size_t, std::size_t);
113  void __trace_vector_to_list_iterate(const void*, std::size_t);
114  void __trace_vector_to_list_invalid_operator(const void*);
115  void __trace_vector_to_list_resize(const void*, std::size_t, std::size_t);
116  void __trace_vector_to_list_find(const void*, std::size_t);
117 
118  void __trace_list_to_slist_destruct(const void*);
119  void __trace_list_to_slist_construct(const void*);
120  void __trace_list_to_slist_rewind(const void*);
121  void __trace_list_to_slist_operation(const void*);
122 
123  void __trace_list_to_vector_destruct(const void*);
124  void __trace_list_to_vector_construct(const void*);
125  void __trace_list_to_vector_insert(const void*, std::size_t, std::size_t);
126  void __trace_list_to_vector_iterate(const void*, std::size_t);
127  void __trace_list_to_vector_invalid_operator(const void*);
128  void __trace_list_to_vector_resize(const void*, std::size_t, std::size_t);
129 
130  void __trace_list_to_set_destruct(const void*);
131  void __trace_list_to_set_construct(const void*);
132  void __trace_list_to_set_insert(const void*, std::size_t, std::size_t);
133  void __trace_list_to_set_iterate(const void*, std::size_t);
134  void __trace_list_to_set_invalid_operator(const void*);
135  void __trace_list_to_set_find(const void*, std::size_t);
136 
137  void __trace_map_to_unordered_map_construct(const void*);
138  void __trace_map_to_unordered_map_invalidate(const void*);
139  void __trace_map_to_unordered_map_insert(const void*, std::size_t,
140  std::size_t);
141  void __trace_map_to_unordered_map_erase(const void*, std::size_t,
142  std::size_t);
143  void __trace_map_to_unordered_map_iterate(const void*, std::size_t);
144  void __trace_map_to_unordered_map_find(const void*, std::size_t);
145  void __trace_map_to_unordered_map_destruct(const void*);
146 } // namespace __gnu_profile
147 
148 // Master switch turns on all diagnostics that are not explicitly turned off.
149 #ifdef _GLIBCXX_PROFILE
150 #ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_SMALL
151 #define _GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL
152 #endif
153 #ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_LARGE
154 #define _GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE
155 #endif
156 #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_SMALL
157 #define _GLIBCXX_PROFILE_VECTOR_TOO_SMALL
158 #endif
159 #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_LARGE
160 #define _GLIBCXX_PROFILE_VECTOR_TOO_LARGE
161 #endif
162 #ifndef _GLIBCXX_PROFILE_NO_INEFFICIENT_HASH
163 #define _GLIBCXX_PROFILE_INEFFICIENT_HASH
164 #endif
165 #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TO_LIST
166 #define _GLIBCXX_PROFILE_VECTOR_TO_LIST
167 #endif
168 #ifndef _GLIBCXX_PROFILE_NO_LIST_TO_SLIST
169 #define _GLIBCXX_PROFILE_LIST_TO_SLIST
170 #endif
171 #ifndef _GLIBCXX_PROFILE_NO_LIST_TO_VECTOR
172 #define _GLIBCXX_PROFILE_LIST_TO_VECTOR
173 #endif
174 #ifndef _GLIBCXX_PROFILE_NO_MAP_TO_UNORDERED_MAP
175 #define _GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP
176 #endif
177 #endif
178 
179 // Expose global management routines to user code.
180 #ifdef _GLIBCXX_PROFILE
181 #define __profcxx_report() \
182  _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__report())
183 #define __profcxx_turn_on() \
184  _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__turn_on())
185 #define __profcxx_turn_off() \
186  _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__turn_off())
187 #define __profcxx_is_invalid() \
188  _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__is_invalid())
189 #define __profcxx_is_on() \
190  _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__is_on())
191 #define __profcxx_is_off() \
192  _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__is_off())
193 #else
194 #define __profcxx_report()
195 #define __profcxx_turn_on()
196 #define __profcxx_turn_off()
197 #define __profcxx_is_invalid()
198 #define __profcxx_is_on()
199 #define __profcxx_is_off()
200 #endif
201 
202 // Turn on/off instrumentation for HASHTABLE_TOO_SMALL and HASHTABLE_TOO_LARGE.
203 #if (defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL) \
204  || defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE))
205 #define __profcxx_hashtable_resize(__x...) \
206  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
207  __gnu_profile::__trace_hashtable_size_resize(__x))
208 #define __profcxx_hashtable_destruct(__x...) \
209  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
210  __gnu_profile::__trace_hashtable_size_destruct(__x))
211 #define __profcxx_hashtable_construct(__x...) \
212  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
213  __gnu_profile::__trace_hashtable_size_construct(__x))
214 #else
215 #define __profcxx_hashtable_resize(__x...)
216 #define __profcxx_hashtable_destruct(__x...)
217 #define __profcxx_hashtable_construct(__x...)
218 #endif
219 
220 // Turn on/off instrumentation for VECTOR_TOO_SMALL and VECTOR_TOO_LARGE.
221 #if (defined(_GLIBCXX_PROFILE_VECTOR_TOO_SMALL) \
222  || defined(_GLIBCXX_PROFILE_VECTOR_TOO_LARGE))
223 #define __profcxx_vector_resize(__x...) \
224  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
225  __gnu_profile::__trace_vector_size_resize(__x))
226 #define __profcxx_vector_destruct(__x...) \
227  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
228  __gnu_profile::__trace_vector_size_destruct(__x))
229 #define __profcxx_vector_construct(__x...) \
230  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
231  __gnu_profile::__trace_vector_size_construct(__x))
232 #else
233 #define __profcxx_vector_resize(__x...)
234 #define __profcxx_vector_destruct(__x...)
235 #define __profcxx_vector_construct(__x...)
236 #endif
237 
238 // Turn on/off instrumentation for INEFFICIENT_HASH.
239 #if defined(_GLIBCXX_PROFILE_INEFFICIENT_HASH)
240 #define __profcxx_inefficient_hash_is_on() \
241  __gnu_profile::__is_on()
242 #define __profcxx_hashtable_construct2(__x...) \
243  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
244  __gnu_profile::__trace_hash_func_construct(__x))
245 #define __profcxx_hashtable_destruct2(__x...) \
246  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
247  __gnu_profile::__trace_hash_func_destruct(__x))
248 #else
249 #define __profcxx_inefficient_hash_is_on() false
250 #define __profcxx_hashtable_destruct2(__x...)
251 #define __profcxx_hashtable_construct2(__x...)
252 #endif
253 
254 // Turn on/off instrumentation for VECTOR_TO_LIST.
255 #if defined(_GLIBCXX_PROFILE_VECTOR_TO_LIST)
256 #define __profcxx_vector_construct2(__x...) \
257  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
258  __gnu_profile::__trace_vector_to_list_construct(__x))
259 #define __profcxx_vector_destruct2(__x...) \
260  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
261  __gnu_profile::__trace_vector_to_list_destruct(__x))
262 #define __profcxx_vector_insert(__x...) \
263  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
264  __gnu_profile::__trace_vector_to_list_insert(__x))
265 #define __profcxx_vector_iterate(__x...) \
266  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
267  __gnu_profile::__trace_vector_to_list_iterate(__x))
268 #define __profcxx_vector_invalid_operator(__x...) \
269  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
270  __gnu_profile::__trace_vector_to_list_invalid_operator(__x))
271 #define __profcxx_vector_resize2(__x...) \
272  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
273  __gnu_profile::__trace_vector_to_list_resize(__x))
274 #define __profcxx_vector_find(__x...) \
275  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
276  __gnu_profile::__trace_vector_to_list_find(__x))
277 #else
278 #define __profcxx_vector_destruct2(__x...)
279 #define __profcxx_vector_construct2(__x...)
280 #define __profcxx_vector_insert(__x...)
281 #define __profcxx_vector_iterate(__x...)
282 #define __profcxx_vector_invalid_operator(__x...)
283 #define __profcxx_vector_resize2(__x...)
284 #define __profcxx_vector_find(__x...)
285 #endif
286 
287 // Turn on/off instrumentation for LIST_TO_VECTOR.
288 #if defined(_GLIBCXX_PROFILE_LIST_TO_VECTOR)
289 #define __profcxx_list_construct2(__x...) \
290  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
291  __gnu_profile::__trace_list_to_vector_construct(__x))
292 #define __profcxx_list_destruct2(__x...) \
293  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
294  __gnu_profile::__trace_list_to_vector_destruct(__x))
295 #define __profcxx_list_insert(__x...) \
296  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
297  __gnu_profile::__trace_list_to_vector_insert(__x))
298 #define __profcxx_list_iterate(__x...) \
299  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
300  __gnu_profile::__trace_list_to_vector_iterate(__x))
301 #define __profcxx_list_invalid_operator(__x...) \
302  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
303  __gnu_profile::__trace_list_to_vector_invalid_operator(__x))
304 #else
305 #define __profcxx_list_destruct2(__x...)
306 #define __profcxx_list_construct2(__x...)
307 #define __profcxx_list_insert(__x...)
308 #define __profcxx_list_iterate(__x...)
309 #define __profcxx_list_invalid_operator(__x...)
310 #endif
311 
312 // Turn on/off instrumentation for LIST_TO_SLIST.
313 #if defined(_GLIBCXX_PROFILE_LIST_TO_SLIST)
314 #define __profcxx_list_rewind(__x...) \
315  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
316  __gnu_profile::__trace_list_to_slist_rewind(__x))
317 #define __profcxx_list_operation(__x...) \
318  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
319  __gnu_profile::__trace_list_to_slist_operation(__x))
320 #define __profcxx_list_destruct(__x...) \
321  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
322  __gnu_profile::__trace_list_to_slist_destruct(__x))
323 #define __profcxx_list_construct(__x...) \
324  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
325  __gnu_profile::__trace_list_to_slist_construct(__x))
326 #else
327 #define __profcxx_list_rewind(__x...)
328 #define __profcxx_list_operation(__x...)
329 #define __profcxx_list_destruct(__x...)
330 #define __profcxx_list_construct(__x...)
331 #endif
332 
333 // Turn on/off instrumentation for MAP_TO_UNORDERED_MAP.
334 #if defined(_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP)
335 #define __profcxx_map_to_unordered_map_construct(__x...) \
336  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
337  __gnu_profile::__trace_map_to_unordered_map_construct(__x))
338 #define __profcxx_map_to_unordered_map_destruct(__x...) \
339  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
340  __gnu_profile::__trace_map_to_unordered_map_destruct(__x))
341 #define __profcxx_map_to_unordered_map_insert(__x...) \
342  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
343  __gnu_profile::__trace_map_to_unordered_map_insert(__x))
344 #define __profcxx_map_to_unordered_map_erase(__x...) \
345  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
346  __gnu_profile::__trace_map_to_unordered_map_erase(__x))
347 #define __profcxx_map_to_unordered_map_iterate(__x...) \
348  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
349  __gnu_profile::__trace_map_to_unordered_map_iterate(__x))
350 #define __profcxx_map_to_unordered_map_invalidate(__x...) \
351  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
352  __gnu_profile::__trace_map_to_unordered_map_invalidate(__x))
353 #define __profcxx_map_to_unordered_map_find(__x...) \
354  _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
355  __gnu_profile::__trace_map_to_unordered_map_find(__x))
356 #else
357 #define __profcxx_map_to_unordered_map_construct(__x...) \
358 
359 #define __profcxx_map_to_unordered_map_destruct(__x...)
360 #define __profcxx_map_to_unordered_map_insert(__x...)
361 #define __profcxx_map_to_unordered_map_erase(__x...)
362 #define __profcxx_map_to_unordered_map_iterate(__x...)
363 #define __profcxx_map_to_unordered_map_invalidate(__x...)
364 #define __profcxx_map_to_unordered_map_find(__x...)
365 #endif
366 
367 // Set default values for compile-time customizable variables.
368 #ifndef _GLIBCXX_PROFILE_TRACE_PATH_ROOT
369 #define _GLIBCXX_PROFILE_TRACE_PATH_ROOT "libstdcxx-profile"
370 #endif
371 #ifndef _GLIBCXX_PROFILE_TRACE_ENV_VAR
372 #define _GLIBCXX_PROFILE_TRACE_ENV_VAR "_GLIBCXX_PROFILE_TRACE_PATH_ROOT"
373 #endif
374 #ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR
375 #define _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR \
376  "_GLIBCXX_PROFILE_MAX_WARN_COUNT"
377 #endif
378 #ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT
379 #define _GLIBCXX_PROFILE_MAX_WARN_COUNT 10
380 #endif
381 #ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH
382 #define _GLIBCXX_PROFILE_MAX_STACK_DEPTH 32
383 #endif
384 #ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR
385 #define _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR \
386  "_GLIBCXX_PROFILE_MAX_STACK_DEPTH"
387 #endif
388 #ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC
389 #define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC (1 << 28)
390 #endif
391 #ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR
392 #define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR \
393  "_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC"
394 #endif
395 
396 // Instrumentation hook implementations.
404 
405 #endif // _GLIBCXX_PROFILE_PROFILER_H
void __report(void)
Final report method, registered with atexit.
Collection of hashtable size traces.
diagnostics for vector to list.
Data structures to represent profiling traces.
diagnostics for list to vector.
Collection of vector size traces.
GNU profile code for public use.
Diagnostics for map to unordered_map.
Diagnostics for list to slist.