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 */ 58 struct __reentrance_guard 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. 397 #include "profile/impl/profiler_hash_func.h" 398 #include "profile/impl/profiler_hashtable_size.h" 399 #include "profile/impl/profiler_map_to_unordered_map.h" 400 #include "profile/impl/profiler_vector_size.h" 401 #include "profile/impl/profiler_vector_to_list.h" 402 #include "profile/impl/profiler_list_to_slist.h" 403 #include "profile/impl/profiler_list_to_vector.h" 404 405 #endif // _GLIBCXX_PROFILE_PROFILER_H 406