Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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.