The Battle for Wesnoth  1.15.1+dev
tracer.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2012 - 2018 by Mark de Wever <koraq@xs4all.nl>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Contains code for tracing the code.
18  */
19 
20 #pragma once
21 
22 #include <map>
23 #include <string>
24 
25 /** Helper structure for gathering the tracing statistics. */
26 struct tracer
27 {
28  /**
29  * Helper structure to print the tracing statistics.
30  *
31  * When the constructor gets a valid @ref tracer pointer it prints the
32  * tracing statistics in its destructor. This allows the structure to be
33  * initialised at the beginning of a scope and print the statistics once
34  * the scope is left. (This makes it easier to write the tracing macros.)
35  */
36  struct printer
37  {
38  printer(const printer&) = delete;
39  printer& operator=(const printer&) = delete;
40 
41  explicit printer(const tracer* const tracer__);
42 
43  ~printer();
44 
45  /** The tracer, whose statistics to print. */
46  const tracer* const tracer_;
47  };
48 
49  tracer(const tracer&) = delete;
50  tracer& operator=(const tracer&) = delete;
51 
52  explicit tracer(const char* const function__);
53 
54  /** The total number of runs. */
55  int run;
56 
57  /** The function being traced. */
58  const char* const function;
59 
60  /**
61  * The tracer counters.
62  *
63  * The first pair contains a line number and a name of the marker.
64  * This has two advantages:
65  * * A line number is always unique, thus if using markers with the same
66  * name, they are not the same marker.
67  * * The markers are sorted in order of appearance and not in order of
68  * their names.
69  *
70  * The second pair contains the number of times a marker is hit.
71  */
72  std::map<std::pair<int, std::string>, int> counters;
73 };
74 
75 /**
76  * The beginning of a traced scope.
77  *
78  * It is not intended that tracer scopes are nested, but it should work at the
79  * moment.
80  *
81  * @param interval The interval between printing the statistics.
82  */
83 #ifdef __GNUC__
84 #define TRACER_ENTRY(interval) \
85  static struct tracer tracer(__PRETTY_FUNCTION__); \
86  tracer::printer print((++tracer.run % interval) == 0 ? &tracer : nullptr)
87 #else
88 #define TRACER_ENTRY(interval) \
89  static struct tracer tracer(__FUNCTION__); \
90  tracer::printer print((++tracer.run % interval) == 0 ? &tracer : nullptr)
91 #endif
92 
93 /**
94  * A trace count point.
95  *
96  * When this macro is reached the counter for this marker is increased.
97  *
98  * @param marker A string with the name of the marker.
99  */
100 #define TRACER_COUNT(marker) \
101  do { \
102  ++tracer.counters[std::make_pair(__LINE__, marker)]; \
103  } while(0)
Helper structure to print the tracing statistics.
Definition: tracer.hpp:36
const tracer *const tracer_
The tracer, whose statistics to print.
Definition: tracer.hpp:46
int run
The total number of runs.
Definition: tracer.hpp:55
printer & operator=(const printer &)=delete
printer(const printer &)=delete
tracer(const tracer &)=delete
Helper structure for gathering the tracing statistics.
Definition: tracer.hpp:26
std::map< std::pair< int, std::string >, int > counters
The tracer counters.
Definition: tracer.hpp:72