]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/profile/impl/profiler_trace.h
c++config (std::size_t, [...]): Provide typedefs.
[thirdparty/gcc.git] / libstdc++-v3 / include / profile / impl / profiler_trace.h
CommitLineData
1218d701
SR
1// -*- C++ -*-
2//
2a60a9f6 3// Copyright (C) 2009, 2010 Free Software Foundation, Inc.
1218d701
SR
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 terms
7// of the GNU General Public License as published by the Free Software
8// Foundation; either version 2, or (at your option) any later
9// version.
10
11// This library is distributed in the hope that it will be useful, but
12// WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this library; see the file COPYING. If not, write to
18// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19// MA 02111-1307, USA.
20
21// As a special exception, you may use this file as part of a free
22// software library without restriction. Specifically, if other files
23// instantiate templates or use macros or inline functions from this
24// file, or you compile this file and link it with other files to
25// produce an executable, this file does not by itself cause the
26// resulting executable to be covered by the GNU General Public
27// License. This exception does not however invalidate any other
28// reasons why the executable file might be covered by the GNU General
29// Public License.
30
31/** @file profile/impl/profiler_trace.h
32 * @brief Data structures to represent profiling traces.
33 */
34
35// Written by Lixia Liu and Silvius Rus.
36
6b223191
BK
37#ifndef _GLIBCXX_PROFILE_PROFILER_TRACE_H
38#define _GLIBCXX_PROFILE_PROFILER_TRACE_H 1
1218d701
SR
39
40#ifdef __GXX_EXPERIMENTAL_CXX0X__
41#include <cerrno>
42#include <cstdint>
43#include <cstdio>
44#include <cstdlib>
45#define _GLIBCXX_IMPL_UNORDERED_MAP std::_GLIBCXX_STD_PR::unordered_map
46#include <unordered_map>
47#else
48#include <errno.h>
49#include <stdint.h>
50#include <stdio.h>
51#include <stdlib.h>
52#include <tr1/unordered_map>
53#define _GLIBCXX_IMPL_UNORDERED_MAP std::tr1::unordered_map
54#endif
55
1f0622b4 56#include <ext/concurrence.h>
a1360f57
SR
57#include <fstream>
58#include <string>
1218d701 59#include <utility>
1f0622b4 60#include <vector>
1218d701 61
1f0622b4 62#include "profile/impl/profiler_algos.h"
1218d701
SR
63#include "profile/impl/profiler_state.h"
64#include "profile/impl/profiler_node.h"
65
9ee6a740 66namespace __gnu_profile
1218d701 67{
1f0622b4
SR
68/** @brief Internal environment. Values can be set one of two ways:
69 1. In config file "var = value". The default config file path is
70 libstdcxx-profile.conf.
71 2. By setting process environment variables. For instance, in a Bash
72 shell you can set the unit cost of iterating through a map like this:
73 export __map_iterate_cost_factor=5.0.
74 If a value is set both in the input file and through an environment
75 variable, the environment value takes precedence. */
76typedef _GLIBCXX_IMPL_UNORDERED_MAP<std::string, std::string> __env_t;
77_GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__env_t, __env);
78
79/** @brief Master lock. */
80_GLIBCXX_PROFILE_DEFINE_UNINIT_DATA(__gnu_cxx::__mutex, __global_lock);
1218d701 81
a1360f57
SR
82/** @brief Representation of a warning. */
83struct __warning_data
84{
85 float __magnitude;
86 __stack_t __context;
87 const char* __warning_id;
88 const char* __warning_message;
f0999267 89 __warning_data()
8fc81078
PC
90 : __magnitude(0.0), __context(0), __warning_id(0),
91 __warning_message(0) { }
f0999267
PC
92 __warning_data(float __m, __stack_t __c, const char* __id,
93 const char* __msg)
1f0622b4 94 : __magnitude(__m), __context(__c), __warning_id(__id),
f0999267 95 __warning_message(__msg) { }
1f0622b4
SR
96 bool operator<(const struct __warning_data& __other) const
97 { return __magnitude < __other.__magnitude; }
f0999267 98};
a1360f57
SR
99
100typedef std::_GLIBCXX_STD_PR::vector<__warning_data> __warning_vector_t;
101
102// Defined in profiler_<diagnostic name>.h.
103class __trace_hash_func;
104class __trace_hashtable_size;
105class __trace_map2umap;
106class __trace_vector_size;
107class __trace_vector_to_list;
108class __trace_list_to_slist;
109class __trace_list_to_vector;
110void __trace_vector_size_init();
111void __trace_hashtable_size_init();
112void __trace_hash_func_init();
113void __trace_vector_to_list_init();
114void __trace_list_to_slist_init();
115void __trace_list_to_vector_init();
116void __trace_map_to_unordered_map_init();
117void __trace_vector_size_report(FILE*, __warning_vector_t&);
118void __trace_hashtable_size_report(FILE*, __warning_vector_t&);
119void __trace_hash_func_report(FILE*, __warning_vector_t&);
120void __trace_vector_to_list_report(FILE*, __warning_vector_t&);
121void __trace_list_to_slist_report(FILE*, __warning_vector_t&);
122void __trace_list_to_vector_report(FILE*, __warning_vector_t&);
123void __trace_map_to_unordered_map_report(FILE*, __warning_vector_t&);
124
125// Utility functions.
126inline size_t __max(size_t __a, size_t __b)
127{
128 return __a >= __b ? __a : __b;
129}
1218d701 130
a1360f57
SR
131inline size_t __min(size_t __a, size_t __b)
132{
133 return __a <= __b ? __a : __b;
134}
135
136struct __cost_factor
137{
138 const char* __env_var;
139 float __value;
140};
141
142typedef std::_GLIBCXX_STD_PR::vector<__cost_factor*> __cost_factor_vector;
143
8fc81078
PC
144_GLIBCXX_PROFILE_DEFINE_DATA(__trace_hash_func*, _S_hash_func, 0);
145_GLIBCXX_PROFILE_DEFINE_DATA(__trace_hashtable_size*, _S_hashtable_size, 0);
146_GLIBCXX_PROFILE_DEFINE_DATA(__trace_map2umap*, _S_map2umap, 0);
147_GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_size*, _S_vector_size, 0);
148_GLIBCXX_PROFILE_DEFINE_DATA(__trace_vector_to_list*, _S_vector_to_list, 0);
149_GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_slist*, _S_list_to_slist, 0);
150_GLIBCXX_PROFILE_DEFINE_DATA(__trace_list_to_vector*, _S_list_to_vector, 0);
a1360f57
SR
151
152_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_shift_cost_factor,
153 {"__vector_shift_cost_factor", 1.0});
154_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_iterate_cost_factor,
155 {"__vector_iterate_cost_factor", 1.0});
156_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __vector_resize_cost_factor,
157 {"__vector_resize_cost_factor", 1.0});
158_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_shift_cost_factor,
159 {"__list_shift_cost_factor", 0.0});
160_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_iterate_cost_factor,
161 {"__list_iterate_cost_factor", 10.0});
162_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __list_resize_cost_factor,
163 {"__list_resize_cost_factor", 0.0});
164_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_insert_cost_factor,
165 {"__map_insert_cost_factor", 1.5});
166_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_erase_cost_factor,
167 {"__map_erase_cost_factor", 1.5});
168_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_find_cost_factor,
169 {"__map_find_cost_factor", 1});
170_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __map_iterate_cost_factor,
171 {"__map_iterate_cost_factor", 2.3});
172_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_insert_cost_factor,
173 {"__umap_insert_cost_factor", 12.0});
174_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_erase_cost_factor,
175 {"__umap_erase_cost_factor", 12.0});
176_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_find_cost_factor,
177 {"__umap_find_cost_factor", 10.0});
178_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor, __umap_iterate_cost_factor,
179 {"__umap_iterate_cost_factor", 1.7});
8fc81078 180_GLIBCXX_PROFILE_DEFINE_DATA(__cost_factor_vector*, __cost_factors, 0);
a1360f57
SR
181
182_GLIBCXX_PROFILE_DEFINE_DATA(const char*, _S_trace_file_name,
183 _GLIBCXX_PROFILE_TRACE_PATH_ROOT);
184_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_warn_count,
185 _GLIBCXX_PROFILE_MAX_WARN_COUNT);
186_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_stack_depth,
187 _GLIBCXX_PROFILE_MAX_STACK_DEPTH);
188_GLIBCXX_PROFILE_DEFINE_DATA(size_t, _S_max_mem,
189 _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC);
190
191inline size_t __stack_max_depth()
192{
193 return _GLIBCXX_PROFILE_DATA(_S_max_stack_depth);
194}
195
196inline size_t __max_mem()
197{
198 return _GLIBCXX_PROFILE_DATA(_S_max_mem);
199}
200
201/** @brief Base class for all trace producers. */
202template <typename __object_info, typename __stack_info>
203class __trace_base
204{
205 public:
206 __trace_base();
207 virtual ~__trace_base() {}
208
209 void __add_object(__object_t object, __object_info __info);
210 __object_info* __get_object_info(__object_t __object);
211 void __retire_object(__object_t __object);
212 void __write(FILE* f);
213 void __collect_warnings(__warning_vector_t& __warnings);
214
a1360f57 215 private:
1f0622b4
SR
216 __gnu_cxx::__mutex __object_table_lock;
217 __gnu_cxx::__mutex __stack_table_lock;
a1360f57
SR
218 typedef _GLIBCXX_IMPL_UNORDERED_MAP<__object_t,
219 __object_info> __object_table_t;
220 typedef _GLIBCXX_IMPL_UNORDERED_MAP<__stack_t, __stack_info, __stack_hash,
221 __stack_hash> __stack_table_t;
222 __object_table_t __object_table;
223 __stack_table_t __stack_table;
224 size_t __stack_table_byte_size;
225
226 protected:
227 const char* __id;
228};
229
230template <typename __object_info, typename __stack_info>
231void __trace_base<__object_info, __stack_info>::__collect_warnings(
232 __warning_vector_t& __warnings)
233{
234 typename __stack_table_t::iterator __i = __stack_table.begin();
1f0622b4 235 for (; __i != __stack_table.end(); ++__i)
1218d701 236 {
a1360f57
SR
237 __warnings.push_back(__warning_data((*__i).second.__magnitude(),
238 (*__i).first,
239 __id,
240 (*__i).second.__advice()));
1218d701 241 }
a1360f57 242}
1218d701 243
a1360f57
SR
244template <typename __object_info, typename __stack_info>
245__trace_base<__object_info, __stack_info>::__trace_base()
246{
247 // Do not pick the initial size too large, as we don't know which diagnostics
248 // are more active.
249 __object_table.rehash(10000);
250 __stack_table.rehash(10000);
251 __stack_table_byte_size = 0;
8fc81078 252 __id = 0;
a1360f57
SR
253}
254
255template <typename __object_info, typename __stack_info>
256void __trace_base<__object_info, __stack_info>::__add_object(
257 __object_t __object, __object_info __info)
258{
259 if (__max_mem() == 0
260 || __object_table.size() * sizeof(__object_info) <= __max_mem()) {
1f0622b4 261 this->__object_table_lock.lock();
a1360f57
SR
262 __object_table.insert(
263 typename __object_table_t::value_type(__object, __info));
1f0622b4 264 this->__object_table_lock.unlock();
1218d701 265 }
a1360f57 266}
1218d701 267
a1360f57
SR
268template <typename __object_info, typename __stack_info>
269__object_info* __trace_base<__object_info, __stack_info>::__get_object_info(
270 __object_t __object)
271{
272 // XXX: Revisit this to see if we can decrease mutex spans.
273 // Without this mutex, the object table could be rehashed during an
274 // insertion on another thread, which could result in a segfault.
1f0622b4 275 this->__object_table_lock.lock();
a1360f57
SR
276 typename __object_table_t::iterator __object_it =
277 __object_table.find(__object);
278 if (__object_it == __object_table.end()){
1f0622b4 279 this->__object_table_lock.unlock();
8fc81078 280 return 0;
a1360f57 281 } else {
1f0622b4 282 this->__object_table_lock.unlock();
a1360f57 283 return &__object_it->second;
1218d701 284 }
a1360f57 285}
1218d701 286
a1360f57
SR
287template <typename __object_info, typename __stack_info>
288void __trace_base<__object_info, __stack_info>::__retire_object(
289 __object_t __object)
290{
1f0622b4
SR
291 this->__object_table_lock.lock();
292 this->__stack_table_lock.lock();
a1360f57
SR
293 typename __object_table_t::iterator __object_it =
294 __object_table.find(__object);
295 if (__object_it != __object_table.end()){
296 const __object_info& __info = __object_it->second;
297 const __stack_t& __stack = __info.__stack();
298 typename __stack_table_t::iterator __stack_it =
299 __stack_table.find(__stack);
300 if (__stack_it == __stack_table.end()) {
301 // First occurence of this call context.
302 if (__max_mem() == 0 || __stack_table_byte_size < __max_mem()) {
303 __stack_table_byte_size +=
304 (sizeof(__instruction_address_t) * __size(__stack)
305 + sizeof(__stack) + sizeof(__stack_info));
306 __stack_table.insert(make_pair(__stack, __stack_info(__info)));
6b223191 307 }
a1360f57
SR
308 } else {
309 // Merge object info into info summary for this call context.
310 __stack_it->second.__merge(__info);
311 delete __stack;
312 }
313 __object_table.erase(__object);
1218d701 314 }
1f0622b4
SR
315 this->__object_table_lock.unlock();
316 this->__stack_table_lock.unlock();
a1360f57 317}
1218d701 318
a1360f57
SR
319template <typename __object_info, typename __stack_info>
320void __trace_base<__object_info, __stack_info>::__write(FILE* __f)
321{
322 typename __stack_table_t::iterator __it;
323
324 for (__it = __stack_table.begin(); __it != __stack_table.end(); __it++) {
325 if (__it->second.__is_valid()) {
326 fprintf(__f, __id);
327 fprintf(__f, "|");
328 __gnu_profile::__write(__f, __it->first);
329 fprintf(__f, "|");
330 __it->second.__write(__f);
331 }
1218d701 332 }
a1360f57 333}
1218d701 334
a1360f57
SR
335inline size_t __env_to_size_t(const char* __env_var, size_t __default_value)
336{
337 char* __env_value = getenv(__env_var);
338 if (__env_value) {
8fc81078 339 long int __converted_value = strtol(__env_value, 0, 10);
a1360f57
SR
340 if (errno || __converted_value < 0) {
341 fprintf(stderr, "Bad value for environment variable '%s'.\n", __env_var);
342 abort();
343 } else {
344 return static_cast<size_t>(__converted_value);
345 }
346 } else {
347 return __default_value;
1218d701 348 }
a1360f57 349}
1218d701 350
a1360f57
SR
351inline void __set_max_stack_trace_depth()
352{
353 _GLIBCXX_PROFILE_DATA(_S_max_stack_depth) = __env_to_size_t(
354 _GLIBCXX_PROFILE_MAX_STACK_DEPTH_ENV_VAR,
355 _GLIBCXX_PROFILE_DATA(_S_max_stack_depth));
356}
357
358inline void __set_max_mem()
359{
360 _GLIBCXX_PROFILE_DATA(_S_max_mem) = __env_to_size_t(
361 _GLIBCXX_PROFILE_MEM_PER_DIAGNOSTIC_ENV_VAR,
362 _GLIBCXX_PROFILE_DATA(_S_max_mem));
363}
364
1f0622b4 365inline int __log_magnitude(float __f)
a1360f57 366{
1f0622b4
SR
367 const float __log_base = 10.0;
368 int __result = 0;
369 int __sign = 1;
370 if (__f < 0) {
371 __f = -__f;
372 __sign = -1;
1218d701 373 }
1f0622b4
SR
374 while (__f > __log_base) {
375 ++__result;
376 __f /= 10.0;
a1360f57 377 }
1f0622b4 378 return __sign * __result;
a1360f57 379}
1218d701 380
1f0622b4 381inline FILE* __open_output_file(const char* __extension)
a1360f57
SR
382{
383 // The path is made of _S_trace_file_name + "." + extension.
1f0622b4
SR
384 size_t __root_len = strlen(_GLIBCXX_PROFILE_DATA(_S_trace_file_name));
385 size_t __ext_len = strlen(__extension);
386 char* __file_name = new char[__root_len + 1 + __ext_len + 1];
387 memcpy(__file_name, _GLIBCXX_PROFILE_DATA(_S_trace_file_name),
388 __root_len);
389 *(__file_name + __root_len) = '.';
390 memcpy(__file_name + __root_len + 1, __extension, __ext_len + 1);
391 FILE* __out_file = fopen(__file_name, "w");
392 if (__out_file) {
393 return __out_file;
a1360f57 394 } else {
1f0622b4 395 fprintf(stderr, "Could not open trace file '%s'.\n", __file_name);
a1360f57 396 abort();
1218d701 397 }
a1360f57
SR
398}
399
1f0622b4
SR
400struct __warn
401{
402 FILE* __file;
403 __warn(FILE* __f) { __file = __f; }
404
405 void operator() (const __warning_data& __info)
406 {
407 fprintf(__file, __info.__warning_id);
408 fprintf(__file, ": improvement = %d",
409 __log_magnitude(__info.__magnitude));
410 fprintf(__file, ": call stack = ");
411 __gnu_profile::__write(__file, __info.__context);
412 fprintf(__file, ": advice = %s\n", __info.__warning_message);
413 free(const_cast<void*>
414 (reinterpret_cast<const void*>(__info.__warning_message)));
415 }
416};
417
2a60a9f6 418/** @brief Final report method, registered with @b atexit.
a1360f57
SR
419 *
420 * This can also be called directly by user code, including signal handlers.
421 * It is protected against deadlocks by the reentrance guard in profiler.h.
422 * However, when called from a signal handler that triggers while within
423 * __gnu_profile (under the guarded zone), no output will be produced.
424 */
425inline void __report(void)
426{
1f0622b4 427 _GLIBCXX_PROFILE_DATA(__global_lock).lock();
1218d701 428
1f0622b4 429 __warning_vector_t __warnings, __top_warnings;
1218d701 430
a1360f57
SR
431 FILE* __raw_file = __open_output_file("raw");
432 __trace_vector_size_report(__raw_file, __warnings);
433 __trace_hashtable_size_report(__raw_file, __warnings);
434 __trace_hash_func_report(__raw_file, __warnings);
435 __trace_vector_to_list_report(__raw_file, __warnings);
436 __trace_list_to_slist_report(__raw_file, __warnings);
437 __trace_list_to_vector_report(__raw_file, __warnings);
438 __trace_map_to_unordered_map_report(__raw_file, __warnings);
439 fclose(__raw_file);
1218d701 440
1f0622b4 441 // Sort data by magnitude, keeping just top N.
a1360f57
SR
442 size_t __cutoff = __min(_GLIBCXX_PROFILE_DATA(_S_max_warn_count),
443 __warnings.size());
1f0622b4 444 __top_n(__warnings, __top_warnings, __cutoff);
1218d701 445
a1360f57 446 FILE* __warn_file = __open_output_file("txt");
1f0622b4
SR
447 __for_each(__top_warnings.begin(), __top_warnings.end(),
448 __warn(__warn_file));
a1360f57 449 fclose(__warn_file);
1218d701 450
1f0622b4 451 _GLIBCXX_PROFILE_DATA(__global_lock).unlock();
a1360f57 452}
1218d701 453
a1360f57
SR
454inline void __set_trace_path()
455{
456 char* __env_trace_file_name = getenv(_GLIBCXX_PROFILE_TRACE_ENV_VAR);
1218d701 457
a1360f57
SR
458 if (__env_trace_file_name) {
459 _GLIBCXX_PROFILE_DATA(_S_trace_file_name) = __env_trace_file_name;
1218d701
SR
460 }
461
a1360f57
SR
462 // Make sure early that we can create the trace file.
463 fclose(__open_output_file("txt"));
464}
1218d701 465
a1360f57
SR
466inline void __set_max_warn_count()
467{
468 char* __env_max_warn_count_str = getenv(
469 _GLIBCXX_PROFILE_MAX_WARN_COUNT_ENV_VAR);
1218d701 470
a1360f57
SR
471 if (__env_max_warn_count_str) {
472 _GLIBCXX_PROFILE_DATA(_S_max_warn_count) = static_cast<size_t>(
473 atoi(__env_max_warn_count_str));
1218d701 474 }
a1360f57 475}
1218d701 476
1f0622b4
SR
477inline void
478__read_cost_factors()
a1360f57
SR
479{
480 std::string __conf_file_name(_GLIBCXX_PROFILE_DATA(_S_trace_file_name));
481 __conf_file_name += ".conf";
482
483 std::ifstream __conf_file(__conf_file_name.c_str());
484
f0999267
PC
485 if (__conf_file.is_open())
486 {
487 std::string __line;
488
1f0622b4 489 while (std::getline(__conf_file, __line))
f0999267
PC
490 {
491 std::string::size_type __i = __line.find_first_not_of(" \t\n\v");
492
1f0622b4 493 if (__line.length() <= 0 || __line[__i] == '#')
f0999267
PC
494 // Skip empty lines or comments.
495 continue;
1f0622b4
SR
496 }
497
498 // Trim.
499 __line.erase(__remove(__line.begin(), __line.end(), ' '), __line.end());
500 std::string::size_type __pos = __line.find("=");
501 std::string __factor_name = __line.substr(0, __pos);
502 std::string::size_type __end = __line.find_first_of(";\n");
503 std::string __factor_value = __line.substr(__pos + 1, __end - __pos);
504
505 _GLIBCXX_PROFILE_DATA(__env)[__factor_name] = __factor_value;
1218d701 506 }
a1360f57
SR
507}
508
1f0622b4 509struct __cost_factor_writer
a1360f57 510{
1f0622b4
SR
511 FILE* __file;
512 __cost_factor_writer(FILE* __f) : __file(__f) {}
513 void
514 operator() (const __cost_factor* __factor)
515 { fprintf(__file, "%s = %f\n", __factor->__env_var, __factor->__value); }
516};
f0999267 517
1f0622b4
SR
518inline void
519__write_cost_factors()
520{
521 FILE* __file = __open_output_file("conf.out");
522 __for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(),
523 _GLIBCXX_PROFILE_DATA(__cost_factors)->end(),
524 __cost_factor_writer(__file));
a1360f57
SR
525 fclose(__file);
526}
527
1f0622b4
SR
528struct __cost_factor_setter
529{
530 void operator() (__cost_factor* __factor)
531 {
532 // Look it up in the process environment first.
533 const char* __env_value = getenv(__factor->__env_var);
534
535 if (!__env_value)
536 {
537 // Look it up in the config file.
538 __env_t::iterator it = _GLIBCXX_PROFILE_DATA(__env).find(
539 __factor->__env_var);
540 if (it != _GLIBCXX_PROFILE_DATA(__env).end())
541 __env_value = (*it).second.c_str();
542 }
543
544 if (__env_value)
545 __factor->__value = atof(__env_value);
546 }
547};
548
a1360f57
SR
549inline void __set_cost_factors()
550{
551 _GLIBCXX_PROFILE_DATA(__cost_factors) = new __cost_factor_vector;
552 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
553 &_GLIBCXX_PROFILE_DATA(__vector_shift_cost_factor));
554 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
555 &_GLIBCXX_PROFILE_DATA(__vector_iterate_cost_factor));
556 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
557 &_GLIBCXX_PROFILE_DATA(__vector_resize_cost_factor));
558 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
559 &_GLIBCXX_PROFILE_DATA(__list_shift_cost_factor));
560 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
561 &_GLIBCXX_PROFILE_DATA(__list_iterate_cost_factor));
562 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
563 &_GLIBCXX_PROFILE_DATA(__list_resize_cost_factor));
564 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
565 &_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor));
566 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
567 &_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor));
568 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
569 &_GLIBCXX_PROFILE_DATA(__map_find_cost_factor));
570 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
571 &_GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor));
572 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
573 &_GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor));
574 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
575 &_GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor));
576 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
577 &_GLIBCXX_PROFILE_DATA(__umap_find_cost_factor));
578 _GLIBCXX_PROFILE_DATA(__cost_factors)->push_back(
579 &_GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor));
1f0622b4
SR
580 __for_each(_GLIBCXX_PROFILE_DATA(__cost_factors)->begin(),
581 _GLIBCXX_PROFILE_DATA(__cost_factors)->end(),
582 __cost_factor_setter());
a1360f57
SR
583}
584
585inline void __profcxx_init_unconditional()
586{
1f0622b4 587 _GLIBCXX_PROFILE_DATA(__global_lock).lock();
a1360f57
SR
588
589 if (__is_invalid()) {
6b223191
BK
590
591 __set_max_warn_count();
592
a1360f57
SR
593 if (_GLIBCXX_PROFILE_DATA(_S_max_warn_count) == 0) {
594
595 __turn_off();
596
597 } else {
598
599 __set_max_stack_trace_depth();
600 __set_max_mem();
601 __set_trace_path();
602 __read_cost_factors();
603 __set_cost_factors();
604 __write_cost_factors();
605
606 __trace_vector_size_init();
607 __trace_hashtable_size_init();
608 __trace_hash_func_init();
609 __trace_vector_to_list_init();
610 __trace_list_to_slist_init();
611 __trace_list_to_vector_init();
612 __trace_map_to_unordered_map_init();
613
614 atexit(__report);
615
616 __turn_on();
1218d701 617
a1360f57 618 }
1218d701
SR
619 }
620
1f0622b4 621 _GLIBCXX_PROFILE_DATA(__global_lock).unlock();
a1360f57
SR
622}
623
624/** @brief This function must be called by each instrumentation point.
625 *
626 * The common path is inlined fully.
627 */
628inline bool __profcxx_init(void)
629{
630 if (__is_invalid()) {
631 __profcxx_init_unconditional();
6b223191 632 }
1218d701 633
a1360f57
SR
634 return __is_on();
635}
636
9ee6a740 637} // namespace __gnu_profile
1218d701 638
6b223191 639#endif /* _GLIBCXX_PROFILE_PROFILER_TRACE_H */