Add an assertion.
[dcpomatic.git] / src / lib / timer.cc
1 /*
2     Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic 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
11     DCP-o-matic is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 /** @file src/timer.cc
22  *  @brief Some timing classes for debugging and profiling.
23  */
24
25 #include <iostream>
26 #include <sys/time.h>
27 #include "timer.h"
28 #include "util.h"
29
30 #include "i18n.h"
31
32 using namespace std;
33 using boost::optional;
34
35 /** @param n Name to use when giving output */
36 PeriodTimer::PeriodTimer (string n)
37         : _name (n)
38 {
39         gettimeofday (&_start, 0);
40 }
41
42 /** Destroy PeriodTimer and output the time elapsed since its construction */
43 PeriodTimer::~PeriodTimer ()
44 {
45         struct timeval stop;
46         gettimeofday (&stop, 0);
47         cout << N_("T: ") << _name << N_(": ") << (seconds (stop) - seconds (_start)) << N_("\n");
48 }
49
50 /** @param n Name to use when giving output.
51  *  @param s Initial state.
52  */
53 StateTimer::StateTimer (string n, string s)
54         : _name (n)
55 {
56         struct timeval t;
57         gettimeofday (&t, 0);
58         _time = seconds (t);
59         _state = s;
60 }
61
62 StateTimer::StateTimer (string n)
63         : _name (n)
64 {
65
66 }
67
68 void
69 StateTimer::set (string s)
70 {
71         set_internal (s);
72 }
73
74 /** @param s New state that the caller is in */
75 void
76 StateTimer::set_internal (optional<string> s)
77 {
78         double const last = _time;
79         struct timeval t;
80         gettimeofday (&t, 0);
81         _time = seconds (t);
82
83         if (s && _counts.find(*s) == _counts.end()) {
84                 _counts[*s] = Counts();
85         }
86
87         if (_state) {
88                 _counts[*_state].total_time += _time - last;
89                 _counts[*_state].number++;
90         }
91         _state = s;
92 }
93
94 void
95 StateTimer::unset ()
96 {
97         set_internal (optional<string>());
98 }
99
100 /** Destroy StateTimer and generate a summary of the state timings on cout */
101 StateTimer::~StateTimer ()
102 {
103         if (!_state) {
104                 return;
105         }
106
107         unset ();
108
109         cout << _name << N_(":\n");
110         for (map<string, Counts>::iterator i = _counts.begin(); i != _counts.end(); ++i) {
111                 cout << N_("\t") << i->first << " " << i->second.total_time << " " << i->second.number << " " << (i->second.total_time / i->second.number) << N_("\n");
112         }
113 }