1 /*
2  *    Copyright (C) 2019
3  *    Matthias P. Braendli (matthias.braendli@mpb.li)
4  *
5  *    This file is part of the welle.io.
6  *    Many of the ideas as implemented in welle.io are derived from
7  *    other work, made available through the GNU general Public License.
8  *    All copyrights of the original authors are recognized.
9  *
10  *    welle.io is free software; you can redistribute it and/or modify
11  *    it under the terms of the GNU General Public License as published by
12  *    the Free Software Foundation; either version 2 of the License, or
13  *    (at your option) any later version.
14  *
15  *    welle.io is distributed in the hope that it will be useful,
16  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *    GNU General Public License for more details.
19  *
20  *    You should have received a copy of the GNU General Public License
21  *    along with welle.io; if not, write to the Free Software
22  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23  *
24  */
25 
26 
27 #if defined(WITH_PROFILING)
28 
29 #include <cstdint>
30 #include <ctime>
31 #include <list>
32 #include <unordered_map>
33 #include <thread>
34 #include <mutex>
35 
36 #define PROFILE(m) get_profiler().save_time(ProfilingMark::m)
37 #define PROFILE_FRAME_DECODED() get_profiler().frame_decoded()
38 
39 enum class ProfilingMark {
40     NotSynced,
41     SyncOnEndNull,
42     SyncOnPhase,
43     FindIndex,
44     DataSymbols,
45     PushAllSymbols,
46     OnNewNull,
47     DecodeTII,
48 
49     ProcessPRS,
50     ProcessSymbol,
51     Deinterleaver,
52     FICHandler,
53     MSCHandler,
54     SymbolProcessed,
55 
56     DAGetMSCData,
57     DADeinterleave,
58     DADeconvolve,
59     DADispersal,
60     DADecode,
61     DADone,
62 };
63 
64 struct ProfilingTimepoint {
ProfilingTimepointProfilingTimepoint65     ProfilingTimepoint(
66             struct timespec timestamp,
67             ProfilingMark p) :
68         timestamp(timestamp),
69         p(p) { }
70 
71     struct timespec timestamp;
72     ProfilingMark p;
73 };
74 
75 class Profiler
76 {
77     public:
78         Profiler();
79         Profiler(const Profiler&) = delete;
80         Profiler& operator=(const Profiler&) = delete;
81         ~Profiler();
82 
83         void save_time(const ProfilingMark m);
84         void frame_decoded();
85     private:
86         std::mutex m_mutex;
87         std::unordered_map<
88             std::thread::id,
89             std::list<ProfilingTimepoint> > m_timepoints;
90 
91         struct timespec startup_time_cputime;
92         struct timespec startup_time_monotonic;
93         size_t num_frames_decoded = 0;
94 };
95 
96 Profiler& get_profiler(void);
97 
98 #else
99 # define PROFILE(m)
100 # define PROFILE_FRAME_DECODED()
101 #endif // defined(WITH_PROFILING)
102 
103