# 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