libstdc++
profiler.h
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Copyright (C) 2009, 2010 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the terms
00007 // of the GNU General Public License as published by the Free Software
00008 // Foundation; either version 2, or (at your option) any later
00009 // version.
00010 
00011 // This library is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // General Public License for more details.
00015 
00016 // You should have received a copy of the GNU General Public License
00017 // along with this library; see the file COPYING.  If not, write to
00018 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
00019 // MA 02111-1307, USA.
00020 
00021 // As a special exception, you may use this file as part of a free
00022 // software library without restriction.  Specifically, if other files
00023 // instantiate templates or use macros or inline functions from this
00024 // file, or you compile this file and link it with other files to
00025 // produce an executable, this file does not by itself cause the
00026 // resulting executable to be covered by the GNU General Public
00027 // License.  This exception does not however invalidate any other
00028 // reasons why the executable file might be covered by the GNU General
00029 // Public License.
00030 
00031 /** @file profile/impl/profiler.h
00032  *  @brief Interface of the profiling runtime library.
00033  */
00034 
00035 // Written by Lixia Liu and Silvius Rus.
00036 
00037 #ifndef _GLIBCXX_PROFILE_PROFILER_H
00038 #define _GLIBCXX_PROFILE_PROFILER_H 1
00039 
00040 #include <bits/c++config.h>
00041 
00042 // Mechanism to define data with inline linkage.
00043 #define _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__type, __name)             \
00044   inline __type&                                                        \
00045   __get_##__name()                                                      \
00046   {                                                                     \
00047     static __type __name;                                               \
00048     return __name;                                                      \
00049   }
00050 #define _GLIBCXX_PROFILE_DEFINE_DATA(__type, __name, __initial_value...) \
00051   inline __type& __get_##__name() {                                      \
00052     static __type __name(__initial_value);                               \
00053     return __name;                                                       \
00054   }
00055 #define _GLIBCXX_PROFILE_DATA(__name) \
00056   __get_##__name()
00057 
00058 namespace __gnu_profile
00059 {
00060   /** @brief Reentrance guard.
00061    *
00062    * Mechanism to protect all __gnu_profile operations against recursion,
00063    * multithreaded and exception reentrance.
00064    */
00065   struct __reentrance_guard
00066   {
00067     static bool
00068     __get_in()
00069     {
00070       if (__inside() == true)
00071     return false;
00072       else
00073     {
00074       __inside() = true;
00075       return true;
00076     }
00077     }
00078 
00079     static bool&
00080     __inside()
00081     {
00082       static __thread bool _S_inside(false);
00083       return _S_inside;
00084     }
00085 
00086     __reentrance_guard() { }
00087     ~__reentrance_guard() { __inside() = false; }
00088   };
00089 
00090 #define _GLIBCXX_PROFILE_REENTRANCE_GUARD(__x...)           \
00091   {                                                             \
00092     if (__gnu_profile::__reentrance_guard::__get_in())          \
00093     {                                                           \
00094       __gnu_profile::__reentrance_guard __get_out;      \
00095       __x;                                                      \
00096     }                                                           \
00097   }
00098 
00099   // Forward declarations of implementation functions.
00100   // Don't use any __gnu_profile:: in user code.
00101   // Instead, use the __profcxx... macros, which offer guarded access.
00102   bool __turn_on();
00103   bool __turn_off();
00104   bool __is_invalid();
00105   bool __is_on();
00106   bool __is_off();
00107   void __report(void);
00108   void __trace_hashtable_size_resize(const void*, std::size_t, std::size_t);
00109   void __trace_hashtable_size_destruct(const void*, std::size_t, std::size_t);
00110   void __trace_hashtable_size_construct(const void*, std::size_t);
00111   void __trace_vector_size_resize(const void*, std::size_t, std::size_t);
00112   void __trace_vector_size_destruct(const void*, std::size_t, std::size_t);
00113   void __trace_vector_size_construct(const void*, std::size_t);
00114   void __trace_hash_func_destruct(const void*, std::size_t, std::size_t,
00115                   std::size_t);
00116   void __trace_hash_func_construct(const void*);
00117   void __trace_vector_to_list_destruct(const void*);
00118   void __trace_vector_to_list_construct(const void*);
00119   void __trace_vector_to_list_insert(const void*, std::size_t, std::size_t);
00120   void __trace_vector_to_list_iterate(const void*, std::size_t);
00121   void __trace_vector_to_list_invalid_operator(const void*);
00122   void __trace_vector_to_list_resize(const void*, std::size_t, std::size_t);
00123   void __trace_vector_to_list_find(const void*, std::size_t);
00124 
00125   void __trace_list_to_slist_destruct(const void*);
00126   void __trace_list_to_slist_construct(const void*);
00127   void __trace_list_to_slist_rewind(const void*);
00128   void __trace_list_to_slist_operation(const void*);
00129 
00130   void __trace_list_to_vector_destruct(const void*);
00131   void __trace_list_to_vector_construct(const void*);
00132   void __trace_list_to_vector_insert(const void*, std::size_t, std::size_t);
00133   void __trace_list_to_vector_iterate(const void*, std::size_t);
00134   void __trace_list_to_vector_invalid_operator(const void*);
00135   void __trace_list_to_vector_resize(const void*, std::size_t, std::size_t);
00136 
00137   void __trace_list_to_set_destruct(const void*);
00138   void __trace_list_to_set_construct(const void*);
00139   void __trace_list_to_set_insert(const void*, std::size_t, std::size_t); 
00140   void __trace_list_to_set_iterate(const void*, std::size_t);
00141   void __trace_list_to_set_invalid_operator(const void*);
00142   void __trace_list_to_set_find(const void*, std::size_t); 
00143 
00144   void __trace_map_to_unordered_map_construct(const void*);
00145   void __trace_map_to_unordered_map_invalidate(const void*);
00146   void __trace_map_to_unordered_map_insert(const void*, std::size_t,
00147                        std::size_t);
00148   void __trace_map_to_unordered_map_erase(const void*, std::size_t,
00149                       std::size_t);
00150   void __trace_map_to_unordered_map_iterate(const void*, std::size_t);
00151   void __trace_map_to_unordered_map_find(const void*, std::size_t);
00152   void __trace_map_to_unordered_map_destruct(const void*);
00153 } // namespace __gnu_profile
00154 
00155 // Master switch turns on all diagnostics that are not explicitly turned off.
00156 #ifdef _GLIBCXX_PROFILE
00157 #ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_SMALL
00158 #define _GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL
00159 #endif
00160 #ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_LARGE
00161 #define _GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE
00162 #endif
00163 #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_SMALL
00164 #define _GLIBCXX_PROFILE_VECTOR_TOO_SMALL
00165 #endif
00166 #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_LARGE
00167 #define _GLIBCXX_PROFILE_VECTOR_TOO_LARGE
00168 #endif
00169 #ifndef _GLIBCXX_PROFILE_NO_INEFFICIENT_HASH
00170 #define _GLIBCXX_PROFILE_INEFFICIENT_HASH
00171 #endif
00172 #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TO_LIST
00173 #define _GLIBCXX_PROFILE_VECTOR_TO_LIST
00174 #endif
00175 #ifndef _GLIBCXX_PROFILE_NO_LIST_TO_SLIST
00176 #define _GLIBCXX_PROFILE_LIST_TO_SLIST
00177 #endif
00178 #ifndef _GLIBCXX_PROFILE_NO_LIST_TO_VECTOR
00179 #define _GLIBCXX_PROFILE_LIST_TO_VECTOR
00180 #endif
00181 #ifndef _GLIBCXX_PROFILE_NO_MAP_TO_UNORDERED_MAP
00182 #define _GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP
00183 #endif
00184 #endif
00185 
00186 // Expose global management routines to user code.
00187 #ifdef _GLIBCXX_PROFILE
00188 #define __profcxx_report() \
00189   _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__report())
00190 #define __profcxx_turn_on() \
00191   _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__turn_on())
00192 #define __profcxx_turn_off() \
00193   _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__turn_off())
00194 #define __profcxx_is_invalid() \
00195   _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__is_invalid())
00196 #define __profcxx_is_on() \
00197   _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__is_on())
00198 #define __profcxx__is_off() \
00199   _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__is_off())
00200 #else
00201 #define __profcxx_report()
00202 #define __profcxx_turn_on()
00203 #define __profcxx_turn_off()
00204 #define __profcxx_is_invalid()
00205 #define __profcxx_is_on()
00206 #define __profcxx_is_off()
00207 #endif
00208 
00209 // Turn on/off instrumentation for HASHTABLE_TOO_SMALL and HASHTABLE_TOO_LARGE.
00210 #if (defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL) \
00211      || defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE))
00212 #define __profcxx_hashtable_resize(__x...) \
00213   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00214       __gnu_profile::__trace_hashtable_size_resize(__x))
00215 #define __profcxx_hashtable_destruct(__x...) \
00216   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00217       __gnu_profile::__trace_hashtable_size_destruct(__x))
00218 #define __profcxx_hashtable_construct(__x...) \
00219   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00220       __gnu_profile::__trace_hashtable_size_construct(__x))
00221 #else
00222 #define __profcxx_hashtable_resize(__x...)  
00223 #define __profcxx_hashtable_destruct(__x...) 
00224 #define __profcxx_hashtable_construct(__x...)  
00225 #endif
00226 
00227 // Turn on/off instrumentation for VECTOR_TOO_SMALL and VECTOR_TOO_LARGE.
00228 #if (defined(_GLIBCXX_PROFILE_VECTOR_TOO_SMALL) \
00229      || defined(_GLIBCXX_PROFILE_VECTOR_TOO_LARGE))
00230 #define __profcxx_vector_resize(__x...) \
00231   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00232       __gnu_profile::__trace_vector_size_resize(__x))
00233 #define __profcxx_vector_destruct(__x...) \
00234   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00235       __gnu_profile::__trace_vector_size_destruct(__x))
00236 #define __profcxx_vector_construct(__x...) \
00237   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00238       __gnu_profile::__trace_vector_size_construct(__x))
00239 #else
00240 #define __profcxx_vector_resize(__x...)  
00241 #define __profcxx_vector_destruct(__x...) 
00242 #define __profcxx_vector_construct(__x...)  
00243 #endif 
00244 
00245 // Turn on/off instrumentation for INEFFICIENT_HASH.
00246 #if defined(_GLIBCXX_PROFILE_INEFFICIENT_HASH)
00247 #define __profcxx_hashtable_construct2(__x...) \
00248   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00249       __gnu_profile::__trace_hash_func_construct(__x))
00250 #define __profcxx_hashtable_destruct2(__x...) \
00251   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00252       __gnu_profile::__trace_hash_func_destruct(__x))
00253 #else
00254 #define __profcxx_hashtable_destruct2(__x...) 
00255 #define __profcxx_hashtable_construct2(__x...)  
00256 #endif
00257 
00258 // Turn on/off instrumentation for VECTOR_TO_LIST.
00259 #if defined(_GLIBCXX_PROFILE_VECTOR_TO_LIST)
00260 #define __profcxx_vector_construct2(__x...) \
00261   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00262       __gnu_profile::__trace_vector_to_list_construct(__x))
00263 #define __profcxx_vector_destruct2(__x...) \
00264   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00265       __gnu_profile::__trace_vector_to_list_destruct(__x))
00266 #define __profcxx_vector_insert(__x...) \
00267   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00268       __gnu_profile::__trace_vector_to_list_insert(__x))
00269 #define __profcxx_vector_iterate(__x...) \
00270   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00271       __gnu_profile::__trace_vector_to_list_iterate(__x))
00272 #define __profcxx_vector_invalid_operator(__x...) \
00273   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00274       __gnu_profile::__trace_vector_to_list_invalid_operator(__x))
00275 #define __profcxx_vector_resize2(__x...) \
00276   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00277       __gnu_profile::__trace_vector_to_list_resize(__x))
00278 #define __profcxx_vector_find(__x...) \
00279   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00280       __gnu_profile::__trace_vector_to_list_find(__x))
00281 #else
00282 #define __profcxx_vector_destruct2(__x...)
00283 #define __profcxx_vector_construct2(__x...)
00284 #define __profcxx_vector_insert(__x...)
00285 #define __profcxx_vector_iterate(__x...)
00286 #define __profcxx_vector_invalid_operator(__x...)
00287 #define __profcxx_vector_resize2(__x...)
00288 #define __profcxx_vector_find(__x...)
00289 #endif
00290 
00291 // Turn on/off instrumentation for LIST_TO_VECTOR. 
00292 #if defined(_GLIBCXX_PROFILE_LIST_TO_VECTOR)
00293 #define __profcxx_list_construct2(__x...) \
00294   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00295       __gnu_profile::__trace_list_to_vector_construct(__x))
00296 #define __profcxx_list_destruct2(__x...) \
00297   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00298       __gnu_profile::__trace_list_to_vector_destruct(__x))
00299 #define __profcxx_list_insert(__x...) \
00300   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00301       __gnu_profile::__trace_list_to_vector_insert(__x))
00302 #define __profcxx_list_iterate(__x...) \
00303   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00304       __gnu_profile::__trace_list_to_vector_iterate(__x))
00305 #define __profcxx_list_invalid_operator(__x...) \
00306   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00307       __gnu_profile::__trace_list_to_vector_invalid_operator(__x))
00308 #else
00309 #define __profcxx_list_destruct2(__x...)
00310 #define __profcxx_list_construct2(__x...)
00311 #define __profcxx_list_insert(__x...)
00312 #define __profcxx_list_iterate(__x...)
00313 #define __profcxx_list_invalid_operator(__x...)
00314 #endif
00315 
00316 // Turn on/off instrumentation for LIST_TO_SLIST.  
00317 #if defined(_GLIBCXX_PROFILE_LIST_TO_SLIST)
00318 #define __profcxx_list_rewind(__x...) \
00319   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00320       __gnu_profile::__trace_list_to_slist_rewind(__x))
00321 #define __profcxx_list_operation(__x...) \
00322   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00323       __gnu_profile::__trace_list_to_slist_operation(__x))
00324 #define __profcxx_list_destruct(__x...) \
00325   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00326       __gnu_profile::__trace_list_to_slist_destruct(__x))
00327 #define __profcxx_list_construct(__x...) \
00328   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00329       __gnu_profile::__trace_list_to_slist_construct(__x))
00330 #else
00331 #define __profcxx_list_rewind(__x...)  
00332 #define __profcxx_list_operation(__x...)
00333 #define __profcxx_list_destruct(__x...) 
00334 #define __profcxx_list_construct(__x...)  
00335 #endif 
00336 
00337 // Turn on/off instrumentation for MAP_TO_UNORDERED_MAP.
00338 #if defined(_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP)
00339 #define __profcxx_map_to_unordered_map_construct(__x...) \
00340   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00341       __gnu_profile::__trace_map_to_unordered_map_construct(__x))
00342 #define __profcxx_map_to_unordered_map_destruct(__x...) \
00343   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00344       __gnu_profile::__trace_map_to_unordered_map_destruct(__x))
00345 #define __profcxx_map_to_unordered_map_insert(__x...) \
00346   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00347       __gnu_profile::__trace_map_to_unordered_map_insert(__x))
00348 #define __profcxx_map_to_unordered_map_erase(__x...) \
00349   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00350       __gnu_profile::__trace_map_to_unordered_map_erase(__x))
00351 #define __profcxx_map_to_unordered_map_iterate(__x...) \
00352   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00353       __gnu_profile::__trace_map_to_unordered_map_iterate(__x))
00354 #define __profcxx_map_to_unordered_map_invalidate(__x...) \
00355   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00356       __gnu_profile::__trace_map_to_unordered_map_invalidate(__x))
00357 #define __profcxx_map_to_unordered_map_find(__x...) \
00358   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00359       __gnu_profile::__trace_map_to_unordered_map_find(__x))
00360 #else
00361 #define __profcxx_map_to_unordered_map_construct(__x...) \
00362   
00363 #define __profcxx_map_to_unordered_map_destruct(__x...)
00364 #define __profcxx_map_to_unordered_map_insert(__x...)
00365 #define __profcxx_map_to_unordered_map_erase(__x...)
00366 #define __profcxx_map_to_unordered_map_iterate(__x...)
00367 #define __profcxx_map_to_unordered_map_invalidate(__x...)
00368 #define __profcxx_map_to_unordered_map_find(__x...)
00369 #endif
00370 
00371 // Set default values for compile-time customizable variables.
00372 #ifndef _GLIBCXX_PROFILE_TRACE_PATH_ROOT
00373 #define _GLIBCXX_PROFILE_TRACE_PATH_ROOT "libstdcxx-profile"
00374 #endif
00375 #ifndef _GLIBCXX_PROFILE_TRACE_ENV_VAR
00376 #define _GLIBCXX_PROFILE_TRACE_ENV_VAR "_GLIBCXX_PROFILE_TRACE_PATH_ROOT"
00377 #endif
00378 #ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR
00379 #define _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR \
00380   "_GLIBCXX_PROFILE_MAX_WARN_COUNT"
00381 #endif
00382 #ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT
00383 #define _GLIBCXX_PROFILE_MAX_WARN_COUNT 10
00384 #endif
00385 #ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH
00386 #define _GLIBCXX_PROFILE_MAX_STACK_DEPTH 32
00387 #endif
00388 #ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR
00389 #define _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR \
00390   "_GLIBCXX_PROFILE_MAX_STACK_DEPTH"
00391 #endif
00392 #ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC
00393 #define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC (1 << 28)
00394 #endif
00395 #ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR
00396 #define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR \
00397   "_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC"
00398 #endif
00399 
00400 // Instrumentation hook implementations.
00401 #include "profile/impl/profiler_hash_func.h"
00402 #include "profile/impl/profiler_hashtable_size.h"
00403 #include "profile/impl/profiler_map_to_unordered_map.h"
00404 #include "profile/impl/profiler_vector_size.h"
00405 #include "profile/impl/profiler_vector_to_list.h"
00406 #include "profile/impl/profiler_list_to_slist.h"
00407 #include "profile/impl/profiler_list_to_vector.h"
00408 
00409 #endif // _GLIBCXX_PROFILE_PROFILER_H