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 58namespace __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