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