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