Home | History | Annotate | Download | only in impl
      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