OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [libstdc++-v3/] [include/] [profile/] [impl/] [profiler_trace.h] - Blame information for rev 424

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.