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 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00041 #include <cstddef>
00042 #else
00043 #include <stddef.h>
00044 #endif
00045 
00046 // Mechanism to define data with inline linkage.
00047 #define _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__type, __name)             \
00048   inline __type&                                                        \
00049   __get_##__name()                                                      \
00050   {                                                                     \
00051     static __type __name;                                               \
00052     return __name;                                                      \
00053   }
00054 #define _GLIBCXX_PROFILE_DEFINE_DATA(__type, __name, __initial_value...) \
00055   inline __type& __get_##__name() {                                      \
00056     static __type __name(__initial_value);                               \
00057     return __name;                                                       \
00058   }
00059 #define _GLIBCXX_PROFILE_DATA(__name) \
00060   __get_##__name()
00061 
00062 namespace __gnu_profile
00063 {
00064   /** @brief Reentrance guard.
00065    *
00066    * Mechanism to protect all __gnu_profile operations against recursion,
00067    * multithreaded and exception reentrance.
00068    */
00069   struct __reentrance_guard
00070   {
00071     static bool
00072     __get_in()
00073     {
00074       if (__inside() == true)
00075     return false;
00076       else
00077     {
00078       __inside() = true;
00079       return true;
00080     }
00081     }
00082 
00083     static bool&
00084     __inside()
00085     {
00086       static __thread bool _S_inside(false);
00087       return _S_inside;
00088     }
00089 
00090     __reentrance_guard() { }
00091     ~__reentrance_guard() { __inside() = false; }
00092   };
00093 
00094 #define _GLIBCXX_PROFILE_REENTRANCE_GUARD(__x...)           \
00095   {                                                             \
00096     if (__gnu_profile::__reentrance_guard::__get_in())          \
00097     {                                                           \
00098       __gnu_profile::__reentrance_guard __get_out;      \
00099       __x;                                                      \
00100     }                                                           \
00101   }
00102 
00103   // Forward declarations of implementation functions.
00104   // Don't use any __gnu_profile:: in user code.
00105   // Instead, use the __profcxx... macros, which offer guarded access.
00106   bool __turn_on();
00107   bool __turn_off();
00108   bool __is_invalid();
00109   bool __is_on();
00110   bool __is_off();
00111   void __report(void);
00112   void __trace_hashtable_size_resize(const void*, size_t, size_t);
00113   void __trace_hashtable_size_destruct(const void*, size_t, size_t);
00114   void __trace_hashtable_size_construct(const void*, size_t);
00115   void __trace_vector_size_resize(const void*, size_t, size_t);
00116   void __trace_vector_size_destruct(const void*, size_t, size_t);
00117   void __trace_vector_size_construct(const void*, size_t);
00118   void __trace_hash_func_destruct(const void*, size_t, size_t, size_t);
00119   void __trace_hash_func_construct(const void*);
00120   void __trace_vector_to_list_destruct(const void*);
00121   void __trace_vector_to_list_construct(const void*);
00122   void __trace_vector_to_list_insert(const void*, size_t, size_t);
00123   void __trace_vector_to_list_iterate(const void*, size_t);
00124   void __trace_vector_to_list_invalid_operator(const void*);
00125   void __trace_vector_to_list_resize(const void*, size_t, size_t);
00126   void __trace_vector_to_list_find(const void*, size_t);
00127 
00128   void __trace_list_to_slist_destruct(const void*);
00129   void __trace_list_to_slist_construct(const void*);
00130   void __trace_list_to_slist_rewind(const void*); 
00131   void __trace_list_to_slist_operation(const void*);
00132 
00133   void __trace_list_to_vector_destruct(const void*);
00134   void __trace_list_to_vector_construct(const void*);
00135   void __trace_list_to_vector_insert(const void*, size_t, size_t); 
00136   void __trace_list_to_vector_iterate(const void*, size_t);
00137   void __trace_list_to_vector_invalid_operator(const void*);
00138   void __trace_list_to_vector_resize(const void*, size_t, size_t); 
00139 
00140   void __trace_list_to_set_destruct(const void*);
00141   void __trace_list_to_set_construct(const void*);
00142   void __trace_list_to_set_insert(const void*, size_t, size_t); 
00143   void __trace_list_to_set_iterate(const void*, size_t);
00144   void __trace_list_to_set_invalid_operator(const void*);
00145   void __trace_list_to_set_find(const void*, size_t); 
00146 
00147   void __trace_map_to_unordered_map_construct(const void*);
00148   void __trace_map_to_unordered_map_invalidate(const void*);
00149   void __trace_map_to_unordered_map_insert(const void*, size_t, size_t);
00150   void __trace_map_to_unordered_map_erase(const void*, size_t, size_t);
00151   void __trace_map_to_unordered_map_iterate(const void*, size_t);
00152   void __trace_map_to_unordered_map_find(const void*, size_t);
00153   void __trace_map_to_unordered_map_destruct(const void*);
00154 } // namespace __gnu_profile
00155 
00156 // Master switch turns on all diagnostics that are not explicitly turned off.
00157 #ifdef _GLIBCXX_PROFILE
00158 #ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_SMALL
00159 #define _GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL
00160 #endif
00161 #ifndef _GLIBCXX_PROFILE_NO_HASHTABLE_TOO_LARGE
00162 #define _GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE
00163 #endif
00164 #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_SMALL
00165 #define _GLIBCXX_PROFILE_VECTOR_TOO_SMALL
00166 #endif
00167 #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TOO_LARGE
00168 #define _GLIBCXX_PROFILE_VECTOR_TOO_LARGE
00169 #endif
00170 #ifndef _GLIBCXX_PROFILE_NO_INEFFICIENT_HASH
00171 #define _GLIBCXX_PROFILE_INEFFICIENT_HASH
00172 #endif
00173 #ifndef _GLIBCXX_PROFILE_NO_VECTOR_TO_LIST
00174 #define _GLIBCXX_PROFILE_VECTOR_TO_LIST
00175 #endif
00176 #ifndef _GLIBCXX_PROFILE_NO_LIST_TO_SLIST
00177 #define _GLIBCXX_PROFILE_LIST_TO_SLIST
00178 #endif
00179 #ifndef _GLIBCXX_PROFILE_NO_LIST_TO_VECTOR
00180 #define _GLIBCXX_PROFILE_LIST_TO_VECTOR
00181 #endif
00182 #ifndef _GLIBCXX_PROFILE_NO_MAP_TO_UNORDERED_MAP
00183 #define _GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP
00184 #endif
00185 #endif
00186 
00187 // Expose global management routines to user code.
00188 #ifdef _GLIBCXX_PROFILE
00189 #define __profcxx_report() \
00190   _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__report())
00191 #define __profcxx_turn_on() \
00192   _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__turn_on())
00193 #define __profcxx_turn_off() \
00194   _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__turn_off())
00195 #define __profcxx_is_invalid() \
00196   _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__is_invalid())
00197 #define __profcxx_is_on() \
00198   _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__is_on())
00199 #define __profcxx__is_off() \
00200   _GLIBCXX_PROFILE_REENTRANCE_GUARD(__gnu_profile::__is_off())
00201 #else
00202 #define __profcxx_report()
00203 #define __profcxx_turn_on()
00204 #define __profcxx_turn_off()
00205 #define __profcxx_is_invalid()
00206 #define __profcxx_is_on()
00207 #define __profcxx_is_off()
00208 #endif
00209 
00210 // Turn on/off instrumentation for HASHTABLE_TOO_SMALL and HASHTABLE_TOO_LARGE.
00211 #if (defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_SMALL) \
00212      || defined(_GLIBCXX_PROFILE_HASHTABLE_TOO_LARGE))
00213 #define __profcxx_hashtable_resize(__x...) \
00214   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00215       __gnu_profile::__trace_hashtable_size_resize(__x))
00216 #define __profcxx_hashtable_destruct(__x...) \
00217   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00218       __gnu_profile::__trace_hashtable_size_destruct(__x))
00219 #define __profcxx_hashtable_construct(__x...) \
00220   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00221       __gnu_profile::__trace_hashtable_size_construct(__x))
00222 #else
00223 #define __profcxx_hashtable_resize(__x...)  
00224 #define __profcxx_hashtable_destruct(__x...) 
00225 #define __profcxx_hashtable_construct(__x...)  
00226 #endif
00227 
00228 // Turn on/off instrumentation for VECTOR_TOO_SMALL and VECTOR_TOO_LARGE.
00229 #if (defined(_GLIBCXX_PROFILE_VECTOR_TOO_SMALL) \
00230      || defined(_GLIBCXX_PROFILE_VECTOR_TOO_LARGE))
00231 #define __profcxx_vector_resize(__x...) \
00232   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00233       __gnu_profile::__trace_vector_size_resize(__x))
00234 #define __profcxx_vector_destruct(__x...) \
00235   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00236       __gnu_profile::__trace_vector_size_destruct(__x))
00237 #define __profcxx_vector_construct(__x...) \
00238   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00239       __gnu_profile::__trace_vector_size_construct(__x))
00240 #else
00241 #define __profcxx_vector_resize(__x...)  
00242 #define __profcxx_vector_destruct(__x...) 
00243 #define __profcxx_vector_construct(__x...)  
00244 #endif 
00245 
00246 // Turn on/off instrumentation for INEFFICIENT_HASH.
00247 #if defined(_GLIBCXX_PROFILE_INEFFICIENT_HASH)
00248 #define __profcxx_hashtable_construct2(__x...) \
00249   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00250       __gnu_profile::__trace_hash_func_construct(__x))
00251 #define __profcxx_hashtable_destruct2(__x...) \
00252   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00253       __gnu_profile::__trace_hash_func_destruct(__x))
00254 #else
00255 #define __profcxx_hashtable_destruct2(__x...) 
00256 #define __profcxx_hashtable_construct2(__x...)  
00257 #endif
00258 
00259 // Turn on/off instrumentation for VECTOR_TO_LIST.
00260 #if defined(_GLIBCXX_PROFILE_VECTOR_TO_LIST)
00261 #define __profcxx_vector_construct2(__x...) \
00262   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00263       __gnu_profile::__trace_vector_to_list_construct(__x))
00264 #define __profcxx_vector_destruct2(__x...) \
00265   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00266       __gnu_profile::__trace_vector_to_list_destruct(__x))
00267 #define __profcxx_vector_insert(__x...) \
00268   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00269       __gnu_profile::__trace_vector_to_list_insert(__x))
00270 #define __profcxx_vector_iterate(__x...) \
00271   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00272       __gnu_profile::__trace_vector_to_list_iterate(__x))
00273 #define __profcxx_vector_invalid_operator(__x...) \
00274   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00275       __gnu_profile::__trace_vector_to_list_invalid_operator(__x))
00276 #define __profcxx_vector_resize2(__x...) \
00277   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00278       __gnu_profile::__trace_vector_to_list_resize(__x))
00279 #define __profcxx_vector_find(__x...) \
00280   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00281       __gnu_profile::__trace_vector_to_list_find(__x))
00282 #else
00283 #define __profcxx_vector_destruct2(__x...)
00284 #define __profcxx_vector_construct2(__x...)
00285 #define __profcxx_vector_insert(__x...)
00286 #define __profcxx_vector_iterate(__x...)
00287 #define __profcxx_vector_invalid_operator(__x...)
00288 #define __profcxx_vector_resize2(__x...)
00289 #define __profcxx_vector_find(__x...)
00290 #endif
00291 
00292 // Turn on/off instrumentation for LIST_TO_VECTOR. 
00293 #if defined(_GLIBCXX_PROFILE_LIST_TO_VECTOR)
00294 #define __profcxx_list_construct2(__x...) \
00295   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00296       __gnu_profile::__trace_list_to_vector_construct(__x))
00297 #define __profcxx_list_destruct2(__x...) \
00298   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00299       __gnu_profile::__trace_list_to_vector_destruct(__x))
00300 #define __profcxx_list_insert(__x...) \
00301   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00302       __gnu_profile::__trace_list_to_vector_insert(__x))
00303 #define __profcxx_list_iterate(__x...) \
00304   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00305       __gnu_profile::__trace_list_to_vector_iterate(__x))
00306 #define __profcxx_list_invalid_operator(__x...) \
00307   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00308       __gnu_profile::__trace_list_to_vector_invalid_operator(__x))
00309 #else
00310 #define __profcxx_list_destruct2(__x...)
00311 #define __profcxx_list_construct2(__x...)
00312 #define __profcxx_list_insert(__x...)
00313 #define __profcxx_list_iterate(__x...)
00314 #define __profcxx_list_invalid_operator(__x...)
00315 #endif
00316 
00317 // Turn on/off instrumentation for LIST_TO_SLIST.  
00318 #if defined(_GLIBCXX_PROFILE_LIST_TO_SLIST)
00319 #define __profcxx_list_rewind(__x...) \
00320   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00321       __gnu_profile::__trace_list_to_slist_rewind(__x))
00322 #define __profcxx_list_operation(__x...) \
00323   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00324       __gnu_profile::__trace_list_to_slist_operation(__x))
00325 #define __profcxx_list_destruct(__x...) \
00326   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00327       __gnu_profile::__trace_list_to_slist_destruct(__x))
00328 #define __profcxx_list_construct(__x...) \
00329   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00330       __gnu_profile::__trace_list_to_slist_construct(__x))
00331 #else
00332 #define __profcxx_list_rewind(__x...)  
00333 #define __profcxx_list_operation(__x...)
00334 #define __profcxx_list_destruct(__x...) 
00335 #define __profcxx_list_construct(__x...)  
00336 #endif 
00337 
00338 // Turn on/off instrumentation for MAP_TO_UNORDERED_MAP.
00339 #if defined(_GLIBCXX_PROFILE_MAP_TO_UNORDERED_MAP)
00340 #define __profcxx_map_to_unordered_map_construct(__x...) \
00341   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00342       __gnu_profile::__trace_map_to_unordered_map_construct(__x))
00343 #define __profcxx_map_to_unordered_map_destruct(__x...) \
00344   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00345       __gnu_profile::__trace_map_to_unordered_map_destruct(__x))
00346 #define __profcxx_map_to_unordered_map_insert(__x...) \
00347   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00348       __gnu_profile::__trace_map_to_unordered_map_insert(__x))
00349 #define __profcxx_map_to_unordered_map_erase(__x...) \
00350   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00351       __gnu_profile::__trace_map_to_unordered_map_erase(__x))
00352 #define __profcxx_map_to_unordered_map_iterate(__x...) \
00353   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00354       __gnu_profile::__trace_map_to_unordered_map_iterate(__x))
00355 #define __profcxx_map_to_unordered_map_invalidate(__x...) \
00356   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00357       __gnu_profile::__trace_map_to_unordered_map_invalidate(__x))
00358 #define __profcxx_map_to_unordered_map_find(__x...) \
00359   _GLIBCXX_PROFILE_REENTRANCE_GUARD( \
00360       __gnu_profile::__trace_map_to_unordered_map_find(__x))
00361 #else
00362 #define __profcxx_map_to_unordered_map_construct(__x...) \
00363   
00364 #define __profcxx_map_to_unordered_map_destruct(__x...)
00365 #define __profcxx_map_to_unordered_map_insert(__x...)
00366 #define __profcxx_map_to_unordered_map_erase(__x...)
00367 #define __profcxx_map_to_unordered_map_iterate(__x...)
00368 #define __profcxx_map_to_unordered_map_invalidate(__x...)
00369 #define __profcxx_map_to_unordered_map_find(__x...)
00370 #endif
00371 
00372 // Set default values for compile-time customizable variables.
00373 #ifndef _GLIBCXX_PROFILE_TRACE_PATH_ROOT
00374 #define _GLIBCXX_PROFILE_TRACE_PATH_ROOT "libstdcxx-profile"
00375 #endif
00376 #ifndef _GLIBCXX_PROFILE_TRACE_ENV_VAR
00377 #define _GLIBCXX_PROFILE_TRACE_ENV_VAR "_GLIBCXX_PROFILE_TRACE_PATH_ROOT"
00378 #endif
00379 #ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR
00380 #define _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR \
00381   "_GLIBCXX_PROFILE_MAX_WARN_COUNT"
00382 #endif
00383 #ifndef _GLIBCXX_PROFILE_MAX_WARN_COUNT
00384 #define _GLIBCXX_PROFILE_MAX_WARN_COUNT 10
00385 #endif
00386 #ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH
00387 #define _GLIBCXX_PROFILE_MAX_STACK_DEPTH 32
00388 #endif
00389 #ifndef _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR
00390 #define _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR \
00391   "_GLIBCXX_PROFILE_MAX_STACK_DEPTH"
00392 #endif
00393 #ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC
00394 #define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC 2 << 27
00395 #endif
00396 #ifndef _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR
00397 #define _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR \
00398   "_GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC"
00399 #endif
00400 
00401 // Instrumentation hook implementations.
00402 #include "profile/impl/profiler_hash_func.h"
00403 #include "profile/impl/profiler_hashtable_size.h"
00404 #include "profile/impl/profiler_map_to_unordered_map.h"
00405 #include "profile/impl/profiler_vector_size.h"
00406 #include "profile/impl/profiler_vector_to_list.h"
00407 #include "profile/impl/profiler_list_to_slist.h"
00408 #include "profile/impl/profiler_list_to_vector.h"
00409 
00410 #endif // _GLIBCXX_PROFILE_PROFILER_H