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