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