00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifndef _GLIBCXX_PROFILE_PROFILER_TRACE_H
00038 #define _GLIBCXX_PROFILE_PROFILER_TRACE_H 1
00039
00040 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00041 #include <cerrno>
00042 #include <cstdint>
00043 #include <cstdio>
00044 #include <cstdlib>
00045 #define _GLIBCXX_IMPL_UNORDERED_MAP std::_GLIBCXX_STD_PR::unordered_map
00046 #include <unordered_map>
00047 #else
00048 #include <errno.h>
00049 #include <stdint.h>
00050 #include <stdio.h>
00051 #include <stdlib.h>
00052 #include <tr1/unordered_map>
00053 #define _GLIBCXX_IMPL_UNORDERED_MAP std::tr1::unordered_map
00054 #endif
00055
00056 #include <ext/concurrence.h>
00057 #include <fstream>
00058 #include <string>
00059 #include <utility>
00060 #include <bits/stl_heap.h>
00061
00062 #include "profile/impl/profiler_state.h"
00063 #include "profile/impl/profiler_node.h"
00064
00065 namespace __gnu_profile
00066 {
00067
00068
00069
00070
00071
00072
00073
00074
00075 typedef _GLIBCXX_IMPL_UNORDERED_MAP<std::string, std::string> __env_t;
00076 _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__env_t, __env);
00077
00078
00079 _GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__gnu_cxx::__mutex, __global_lock);
00080
00081
00082 struct __warning_data
00083 {
00084 float __magnitude;
00085 __stack_t __context;
00086 const char* __warning_id;
00087 const char* __warning_message;
00088
00089 __warning_data()
00090 : __magnitude(0.0), __context(NULL), __warning_id(NULL),
00091 __warning_message(NULL) { }
00092
00093 __warning_data(float __m, __stack_t __c, const char* __id,
00094 const char* __msg)
00095 : __magnitude(__m), __context(__c), __warning_id(__id),
00096 __warning_message(__msg) { }
00097
00098 bool
00099 operator>(const struct __warning_data& __other) const
00100 { return __magnitude > __other.__magnitude; }
00101 };
00102
00103 typedef std::_GLIBCXX_STD_PR::vector<__warning_data> __warning_vector_t;
00104
00105
00106 class __trace_hash_func;
00107 class __trace_hashtable_size;
00108 class __trace_map2umap;
00109 class __trace_vector_size;
00110 class __trace_vector_to_list;
00111 class __trace_list_to_slist;
00112 class __trace_list_to_vector;
00113 void __trace_vector_size_init();
00114 void __trace_hashtable_size_init();
00115 void __trace_hash_func_init();
00116 void __trace_vector_to_list_init();
00117 void __trace_list_to_slist_init();
00118 void __trace_list_to_vector_init();
00119 void __trace_map_to_unordered_map_init();
00120 void __trace_vector_size_report(FILE*, __warning_vector_t&);
00121 void __trace_hashtable_size_report(FILE*, __warning_vector_t&);
00122 void __trace_hash_func_report(FILE*, __warning_vector_t&);
00123 void __trace_vector_to_list_report(FILE*, __warning_vector_t&);
00124 void __trace_list_to_slist_report(FILE*, __warning_vector_t&);
00125 void __trace_list_to_vector_report(FILE*, __warning_vector_t&);
00126 void __trace_map_to_unordered_map_report(FILE*, __warning_vector_t&);
00127
00128 struct __cost_factor
00129 {
00130 const char* __env_var;
00131 float __value;
00132 };
00133
00134 typedef std::_GLIBCXX_STD_PR::vector<__cost_factor*> __cost_factor_vector;
00135
00136 _GLIBCXX_PROFILE_DEFINE_DATA(__trace_hash_func*, _S_hash_func, NULL);
00137 _GLIBCXX_PROFILE_DEFINE_DATA(__trace_hashtable_size*, _S_hashtable_size, NULL);
00138 _GLIBCXX_PROFILE_DEFINE_DATA(__trace_map2umap*, _S_map2umap, NULL);
00139 _GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_size*, _S_vector_size, NULL);
00140 _GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_to_list*, _S_vector_to_list, NULL);
00141 _GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_slist*, _S_list_to_slist, NULL);
00142 _GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_vector*, _S_list_to_vector, NULL);
00143
00144 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_shift_cost_factor,
00145 {"__vector_shift_cost_factor", 1.0});
00146 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_iterate_cost_factor,
00147 {"__vector_iterate_cost_factor", 1.0});
00148 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_resize_cost_factor,
00149 {"__vector_resize_cost_factor", 1.0});
00150 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_shift_cost_factor,
00151 {"__list_shift_cost_factor", 0.0});
00152 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_iterate_cost_factor,
00153 {"__list_iterate_cost_factor", 10.0});
00154 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_resize_cost_factor,
00155 {"__list_resize_cost_factor", 0.0});
00156 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_insert_cost_factor,
00157 {"__map_insert_cost_factor", 1.5});
00158 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_erase_cost_factor,
00159 {"__map_erase_cost_factor", 1.5});
00160 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_find_cost_factor,
00161 {"__map_find_cost_factor", 1});
00162 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_iterate_cost_factor,
00163 {"__map_iterate_cost_factor", 2.3});
00164 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_insert_cost_factor,
00165 {"__umap_insert_cost_factor", 12.0});
00166 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_erase_cost_factor,
00167 {"__umap_erase_cost_factor", 12.0});
00168 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_find_cost_factor,
00169 {"__umap_find_cost_factor", 10.0});
00170 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_iterate_cost_factor,
00171 {"__umap_iterate_cost_factor", 1.7});
00172 _GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor_vector*, __cost_factors, NULL);
00173
00174 _GLIBCXX_PROFILE_DEFINE_DATA(const char*, _S_trace_file_name,
00175 _GLIBCXX_PROFILE_TRACE_PATH_ROOT);
00176 _GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_warn_count,
00177 _GLIBCXX_PROFILE_MAX_WARN_COUNT);
00178 _GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_stack_depth,
00179 _GLIBCXX_PROFILE_MAX_STACK_DEPTH);
00180 _GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_mem,
00181 _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC);
00182
00183 inline size_t __stack_max_depth()
00184 {
00185 return _GLIBCXX_PROFILE_DATA(_S_max_stack_depth);
00186 }
00187
00188 inline size_t __max_mem()
00189 {
00190 return _GLIBCXX_PROFILE_DATA(_S_max_mem);
00191 }
00192
00193
00194 template <typename __object_info, typename __stack_info>
00195 class __trace_base
00196 {
00197 public:
00198 __trace_base();
00199 virtual ~__trace_base() {}
00200
00201 void __add_object(__object_t object, __object_info __info);
00202 __object_info* __get_object_info(__object_t __object);
00203 void __retire_object(__object_t __object);
00204 void __write(FILE* f);
00205 void __collect_warnings(__warning_vector_t& __warnings);
00206
00207 private:
00208 __gnu_cxx::__mutex __object_table_lock;
00209 __gnu_cxx::__mutex __stack_table_lock;
00210 typedef _GLIBCXX_IMPL_UNORDERED_MAP<__object_t,
00211 __object_info> __object_table_t;
00212 typedef _GLIBCXX_IMPL_UNORDERED_MAP<__stack_t, __stack_info, __stack_hash,
00213 __stack_hash> __stack_table_t;
00214 __object_table_t __object_table;
00215 __stack_table_t __stack_table;
00216 size_t __stack_table_byte_size;
00217
00218 protected:
00219 const char* __id;
00220 };
00221
00222 template <typename __object_info, typename __stack_info>
00223 void __trace_base<__object_info, __stack_info>::__collect_warnings(
00224 __warning_vector_t& __warnings)
00225 {
00226 typename __stack_table_t::iterator __i = __stack_table.begin();
00227 for ( ; __i != __stack_table.end(); ++__i )
00228 {
00229 __warnings.push_back(__warning_data((*__i).second.__magnitude(),
00230 (*__i).first,
00231 __id,
00232 (*__i).second.__advice()));
00233 }
00234 }
00235
00236 template <typename __object_info, typename __stack_info>
00237 __trace_base<__object_info, __stack_info>::__trace_base()
00238 {
00239
00240
00241 __object_table.rehash(10000);
00242 __stack_table.rehash(10000);
00243 __stack_table_byte_size = 0;
00244 __id = NULL;
00245 }
00246
00247 template <typename __object_info, typename __stack_info>
00248 void __trace_base<__object_info, __stack_info>::__add_object(
00249 __object_t __object, __object_info __info)
00250 {
00251 if (__max_mem() == 0
00252 || __object_table.size() * sizeof(__object_info) <= __max_mem()) {
00253 this->__object_table_lock.lock();
00254 __object_table.insert(
00255 typename __object_table_t::value_type(__object, __info));
00256 this->__object_table_lock.unlock();
00257 }
00258 }
00259
00260 template <typename __object_info, typename __stack_info>
00261 __object_info* __trace_base<__object_info, __stack_info>::__get_object_info(
00262 __object_t __object)
00263 {
00264
00265
00266
00267 this->__object_table_lock.lock();
00268 typename __object_table_t::iterator __object_it =
00269 __object_table.find(__object);
00270 if (__object_it == __object_table.end()){
00271 this->__object_table_lock.unlock();
00272 return NULL;
00273 } else {
00274 this->__object_table_lock.unlock();
00275 return &__object_it->second;
00276 }
00277 }
00278
00279 template <typename __object_info, typename __stack_info>
00280 void __trace_base<__object_info, __stack_info>::__retire_object(
00281 __object_t __object)
00282 {
00283 this->__object_table_lock.lock();
00284 this->__stack_table_lock.lock();
00285 typename __object_table_t::iterator __object_it =
00286 __object_table.find(__object);
00287 if (__object_it != __object_table.end()){
00288 const __object_info& __info = __object_it->second;
00289 const __stack_t& __stack = __info.__stack();
00290 typename __stack_table_t::iterator __stack_it =
00291 __stack_table.find(__stack);
00292 if (__stack_it == __stack_table.end()) {
00293
00294 if (__max_mem() == 0 || __stack_table_byte_size < __max_mem()) {
00295 __stack_table_byte_size +=
00296 (sizeof(__instruction_address_t) * __size(__stack)
00297 + sizeof(__stack) + sizeof(__stack_info));
00298 __stack_table.insert(make_pair(__stack, __stack_info(__info)));
00299 }
00300 } else {
00301
00302 __stack_it->second.__merge(__info);
00303 delete __stack;
00304 }
00305 __object_table.erase(__object);
00306 }
00307 this->__object_table_lock.unlock();
00308 this->__stack_table_lock.unlock();
00309 }
00310
00311 template <typename __object_info, typename __stack_info>
00312 void __trace_base<__object_info, __stack_info>::__write(FILE* __f)
00313 {
00314 typename __stack_table_t::iterator __it;
00315
00316 for (__it = __stack_table.begin(); __it != __stack_table.end(); __it++) {
00317 if (__it->second.__is_valid()) {
00318 fprintf(__f, __id);
00319 fprintf(__f, "|");
00320 __gnu_profile::__write(__f, __it->first);
00321 fprintf(__f, "|");
00322 __it->second.__write(__f);
00323 }
00324 }
00325 }
00326
00327 inline size_t __env_to_size_t(const char* __env_var, size_t __default_value)
00328 {
00329 char* __env_value = getenv(__env_var);
00330 if (__env_value) {
00331 long int __converted_value = strtol(__env_value, NULL, 10);
00332 if (errno || __converted_value < 0) {
00333 fprintf(stderr, "Bad value for environment variable '%s'.\n", __env_var);
00334 abort();
00335 } else {
00336 return static_cast<size_t>(__converted_value);
00337 }
00338 } else {
00339 return __default_value;
00340 }
00341 }
00342
00343 inline void __set_max_stack_trace_depth()
00344 {
00345 _GLIBCXX_PROFILE_DATA(_S_max_stack_depth) = __env_to_size_t(
00346 _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR,
00347 _GLIBCXX_PROFILE_DATA(_S_max_stack_depth));
00348 }
00349
00350 inline void __set_max_mem()
00351 {
00352 _GLIBCXX_PROFILE_DATA(_S_max_mem) = __env_to_size_t(
00353 _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR,
00354 _GLIBCXX_PROFILE_DATA(_S_max_mem));
00355 }
00356
00357 inline int __log_magnitude(float __f)
00358 {
00359 const float __log_base = 10.0;
00360 int __result = 0;
00361 int __sign = 1;
00362 if (__f < 0) {
00363 __f = -__f;
00364 __sign = -1;
00365 }
00366 while (__f > __log_base) {
00367 ++__result;
00368 __f /= 10.0;
00369 }
00370 return __sign * __result;
00371 }
00372
00373 inline FILE* __open_output_file(const char* __extension)
00374 {
00375
00376 size_t __root_len = strlen(_GLIBCXX_PROFILE_DATA(_S_trace_file_name));
00377 size_t __ext_len = strlen(__extension);
00378 char* __file_name = new char[__root_len + 1 + __ext_len + 1];
00379 memcpy(__file_name, _GLIBCXX_PROFILE_DATA(_S_trace_file_name), __root_len);
00380 *(__file_name + __root_len) = '.';
00381 memcpy(__file_name + __root_len + 1, __extension, __ext_len + 1);
00382 FILE* __out_file = fopen(__file_name, "w");
00383 if (__out_file) {
00384 return __out_file;
00385 } else {
00386 fprintf(stderr, "Could not open trace file '%s'.\n", __file_name);
00387 abort();
00388 }
00389 }
00390
00391
00392
00393
00394
00395
00396
00397
00398 inline void __report(void)
00399 {
00400 _GLIBCXX_PROFILE_DATA(__global_lock).lock();
00401
00402 __warning_vector_t __warnings;
00403
00404 FILE* __raw_file = __open_output_file("raw");
00405 __trace_vector_size_report(__raw_file, __warnings);
00406 __trace_hashtable_size_report(__raw_file, __warnings);
00407 __trace_hash_func_report(__raw_file, __warnings);
00408 __trace_vector_to_list_report(__raw_file, __warnings);
00409 __trace_list_to_slist_report(__raw_file, __warnings);
00410 __trace_list_to_vector_report(__raw_file, __warnings);
00411 __trace_map_to_unordered_map_report(__raw_file, __warnings);
00412 fclose(__raw_file);
00413
00414
00415
00416 size_t __cutoff = std::min(_GLIBCXX_PROFILE_DATA(_S_max_warn_count),
00417 __warnings.size());
00418
00419 std::make_heap(__warnings.begin(), __warnings.end(),
00420 std::greater<__warning_vector_t::value_type>());
00421 std::sort_heap(__warnings.begin(), __warnings.end(),
00422 std::greater<__warning_vector_t::value_type>());
00423 __warnings.resize(__cutoff);
00424
00425 FILE* __warn_file = __open_output_file("txt");
00426
00427 for (__warning_vector_t::iterator __it = __warnings.begin();
00428 __it != __warnings.end(); ++__it)
00429 {
00430 fprintf(__warn_file, __it->__warning_id);
00431 fprintf(__warn_file, ": improvement = %d",
00432 __log_magnitude(__it->__magnitude));
00433 fprintf(__warn_file, ": call stack = ");
00434 __gnu_profile::__write(__warn_file, __it->__context);
00435 fprintf(__warn_file, ": advice = %s\n", __it->__warning_message);
00436 free(const_cast<void*>(reinterpret_cast<const void*>
00437 (__it->__warning_message)));
00438 }
00439
00440 fclose(__warn_file);
00441
00442 _GLIBCXX_PROFILE_DATA(__global_lock).unlock();
00443 }
00444
00445 inline void __set_trace_path()
00446 {
00447 char* __env_trace_file_name = getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);
00448
00449 if (__env_trace_file_name) {
00450 _GLIBCXX_PROFILE_DATA(_S_trace_file_name) = __env_trace_file_name;
00451 }
00452
00453
00454 fclose(__open_output_file("txt"));
00455 }
00456
00457 inline void __set_max_warn_count()
00458 {
00459 char* __env_max_warn_count_str = getenv(
00460 _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);
00461
00462 if (__env_max_warn_count_str) {
00463 _GLIBCXX_PROFILE_DATA(_S_max_warn_count) = static_cast<size_t>(
00464 atoi(__env_max_warn_count_str));
00465 }
00466 }
00467
00468 inline void __read_cost_factors()
00469 {
00470 std::string __conf_file_name(_GLIBCXX_PROFILE_DATA(_S_trace_file_name));
00471 __conf_file_name += ".conf";
00472
00473 std::ifstream __conf_file(__conf_file_name.c_str());
00474
00475 if (__conf_file.is_open())
00476 {
00477 std::string __line;
00478
00479 while (getline(__conf_file, __line))
00480 {
00481 std::string::size_type __i = __line.find_first_not_of(" \t\n\v");
00482
00483 if (__line.length() <= 0 || __line[__i] == '#') {
00484
00485 continue;
00486 }
00487
00488
00489 if (__line.begin() != __line.end())
00490 {
00491
00492 std::string::iterator __first = __line.begin();
00493 std::string::iterator __result = __first;
00494 ++__first;
00495 for(; __first != __line.end(); ++__first)
00496 if(!(*__first == ' '))
00497 {
00498 *__result = *__first;
00499 ++__result;
00500 }
00501 __line.erase(__result, __line.end());
00502 }
00503 std::string::size_type __pos = __line.find("=");
00504 std::string __factor_name = __line.substr(0, __pos);
00505 std::string::size_type __end = __line.find_first_of(";\n");
00506 std::string __factor_value = __line.substr(__pos + 1, __end - __pos);
00507
00508 _GLIBCXX_PROFILE_DATA(__env)[__factor_name] = __factor_value;
00509 }
00510 }
00511 }
00512
00513 inline void __write_cost_factors()
00514 {
00515 FILE* __file = __open_output_file("conf.out");
00516
00517 for (__decltype(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin()) __it
00518 = _GLIBCXX_PROFILE_DATA(__cost_factors)->begin();
00519 __it != _GLIBCXX_PROFILE_DATA(__cost_factors)->end(); ++__it)
00520 fprintf(__file, "%s = %f\n", (*__it)->__env_var, (*__it)->__value);
00521
00522 fclose(__file);
00523 }
00524
00525 inline void __set_cost_factors()
00526 {
00527 _GLIBCXX_PROFILE_DATA(__cost_factors) = new __cost_factor_vector;
00528 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
00529 &_GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor));
00530 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
00531 &_GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor));
00532 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
00533 &_GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor));
00534 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
00535 &_GLIBCXX_PROFILE_DATA(__list_shift_cost_factor));
00536 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
00537 &_GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor));
00538 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
00539 &_GLIBCXX_PROFILE_DATA(__list_resize_cost_factor));
00540 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
00541 &_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor));
00542 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
00543 &_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor));
00544 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
00545 &_GLIBCXX_PROFILE_DATA(__map_find_cost_factor));
00546 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
00547 &_GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor));
00548 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
00549 &_GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor));
00550 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
00551 &_GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor));
00552 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
00553 &_GLIBCXX_PROFILE_DATA(__umap_find_cost_factor));
00554 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
00555 &_GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor));
00556
00557 for (__decltype(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin()) __it
00558 = _GLIBCXX_PROFILE_DATA(__cost_factors)->begin();
00559 __it != _GLIBCXX_PROFILE_DATA(__cost_factors)->end(); ++__it)
00560 {
00561 const char* __env_cost_factor = getenv((*__it)->__env_var);
00562 if (!__env_cost_factor)
00563 {
00564 __env_t::iterator __found = _GLIBCXX_PROFILE_DATA(__env).find(
00565 (*__it)->__env_var);
00566 if (__found != _GLIBCXX_PROFILE_DATA(__env).end())
00567 __env_cost_factor = (*__found).second.c_str();
00568 }
00569 if (__env_cost_factor)
00570 (*__it)->__value = atof(__env_cost_factor);
00571 }
00572 }
00573
00574 inline void __profcxx_init_unconditional()
00575 {
00576 _GLIBCXX_PROFILE_DATA(__global_lock).lock();
00577
00578 if (__is_invalid()) {
00579
00580 __set_max_warn_count();
00581
00582 if (_GLIBCXX_PROFILE_DATA(_S_max_warn_count) == 0) {
00583
00584 __turn_off();
00585
00586 } else {
00587
00588 __set_max_stack_trace_depth();
00589 __set_max_mem();
00590 __set_trace_path();
00591 __read_cost_factors();
00592 __set_cost_factors();
00593 __write_cost_factors();
00594
00595 __trace_vector_size_init();
00596 __trace_hashtable_size_init();
00597 __trace_hash_func_init();
00598 __trace_vector_to_list_init();
00599 __trace_list_to_slist_init();
00600 __trace_list_to_vector_init();
00601 __trace_map_to_unordered_map_init();
00602
00603 atexit(__report);
00604
00605 __turn_on();
00606
00607 }
00608 }
00609
00610 _GLIBCXX_PROFILE_DATA(__global_lock).unlock();
00611 }
00612
00613
00614
00615
00616
00617 inline bool __profcxx_init(void)
00618 {
00619 if (__is_invalid()) {
00620 __profcxx_init_unconditional();
00621 }
00622
00623 return __is_on();
00624 }
00625
00626 }
00627
00628 #endif