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