Electroneum
Loading...
Searching...
No Matches
perf_timer.cpp
Go to the documentation of this file.
1// Copyright (c) 2017-Present, Electroneum
2// Copyright (c) 2016-2019, The Monero Project
3//
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without modification, are
7// permitted provided that the following conditions are met:
8//
9// 1. Redistributions of source code must retain the above copyright notice, this list of
10// conditions and the following disclaimer.
11//
12// 2. Redistributions in binary form must reproduce the above copyright notice, this list
13// of conditions and the following disclaimer in the documentation and/or other
14// materials provided with the distribution.
15//
16// 3. Neither the name of the copyright holder nor the names of its contributors may be
17// used to endorse or promote products derived from this software without specific
18// prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30#include <vector>
31#include "misc_os_dependent.h"
32#include "perf_timer.h"
33
34#undef ELECTRONEUM_DEFAULT_LOG_CATEGORY
35#define ELECTRONEUM_DEFAULT_LOG_CATEGORY "perf"
36
37#define PERF_LOG_ALWAYS(level, cat, x) \
38 el::base::Writer(level, __FILE__, __LINE__, ELPP_FUNC, el::base::DispatchAction::FileOnlyLog).construct(cat) << x
39#define PERF_LOG(level, cat, x) \
40 do { \
41 if (ELPP->vRegistry()->allowed(level, cat)) PERF_LOG_ALWAYS(level, cat, x); \
42 } while(0)
43
44namespace tools
45{
47 {
48#if defined(__x86_64__)
49 uint32_t hi, lo;
50 __asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi));
51 return (((uint64_t)hi) << 32) | (uint64_t)lo;
52#else
54#endif
55 }
56
57#ifdef __x86_64__
59 {
62
63 while (1)
64 {
66 if (t1 - t0 > 1*1000000000) break; // work one second
67 }
68
70 uint64_t tpns256 = 256 * (r1 - r0) / (t1 - t0);
71 return tpns256 ? tpns256 : 1;
72 }
73#endif
74
75#ifdef __x86_64__
76 uint64_t ticks_per_ns = get_ticks_per_ns();
77#endif
78
80 {
81#if defined(__x86_64__)
82 return 256 * ticks / ticks_per_ns;
83#else
84 return ticks;
85#endif
86 }
87}
88
89namespace tools
90{
91
93
94static __thread std::vector<LoggingPerformanceTimer*> *performance_timers = NULL;
95
97{
98 if (level != el::Level::Debug && level != el::Level::Trace && level != el::Level::Info
99 && level != el::Level::Warning && level != el::Level::Error && level != el::Level::Fatal)
100 {
101 MERROR("Wrong log level: " << el::LevelHelper::convertToString(level) << ", using Info");
102 level = el::Level::Info;
103 }
105}
106
108{
109 if (paused)
110 ticks = 0;
111 else
113}
114
115LoggingPerformanceTimer::LoggingPerformanceTimer(const std::string &s, const std::string &cat, uint64_t unit, el::Level l): PerformanceTimer(), name(s), cat(cat), unit(unit), level(l)
116{
117 const bool log = ELPP->vRegistry()->allowed(level, cat.c_str());
118 if (!performance_timers)
119 {
120 if (log)
121 PERF_LOG_ALWAYS(level, cat.c_str(), "PERF ----------");
122 performance_timers = new std::vector<LoggingPerformanceTimer*>();
123 performance_timers->reserve(16); // how deep before realloc
124 }
125 else
126 {
127 LoggingPerformanceTimer *pt = performance_timers->back();
128 if (!pt->started && !pt->paused)
129 {
130 if (log)
131 {
132 size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused) ++size;
133 PERF_LOG_ALWAYS(pt->level, cat.c_str(), "PERF " << std::string((size-1) * 2, ' ') << " " << pt->name);
134 }
135 pt->started = true;
136 }
137 }
138 performance_timers->push_back(this);
139}
140
146
148{
149 pause();
150 performance_timers->pop_back();
151 const bool log = ELPP->vRegistry()->allowed(level, cat.c_str());
152 if (log)
153 {
154 char s[12];
155 snprintf(s, sizeof(s), "%8llu ", (unsigned long long)(ticks_to_ns(ticks) / (1000000000 / unit)));
156 size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused || tmp==this) ++size;
157 PERF_LOG_ALWAYS(level, cat.c_str(), "PERF " << s << std::string(size * 2, ' ') << " " << name);
158 }
159 if (performance_timers->empty())
160 {
161 delete performance_timers;
162 performance_timers = NULL;
163 }
164}
165
167{
168 if (paused)
169 return;
171 paused = true;
172}
173
175{
176 if (!paused)
177 return;
179 paused = false;
180}
181
183{
184 if (paused)
185 ticks = 0;
186 else
188}
189
191{
192 uint64_t v = ticks;
193 if (!paused)
194 v = get_tick_count() - v;
195 return ticks_to_ns(v);
196}
197
198}
else if(0==res)
static const char * convertToString(Level level)
Converts level to associated const char*.
LoggingPerformanceTimer(const std::string &s, const std::string &cat, uint64_t unit, el::Level l=el::Level::Info)
PerformanceTimer(bool paused=false)
uint64_t value() const
#define ELPP
#define MERROR(x)
Definition misc_log_ex.h:73
Level
Represents enumeration for severity level used to determine level of logging.
@ Warning
Useful when application has potentially harmful situtaions.
@ Info
Mainly useful to represent current progress of application.
@ Fatal
Severe error information that will presumably abort application.
@ Error
Information representing errors in application but application will keep running.
@ Debug
Informational events most useful for developers to debug application.
@ Trace
Information that can be useful to back-trace certain events - mostly useful than debug logs.
Various Tools.
Definition tools.cpp:31
uint64_t ticks_to_ns(uint64_t ticks)
void set_performance_timer_log_level(el::Level level)
uint64_t get_tick_count()
el::Level performance_timer_log_level
uint64_t get_ticks_per_ns()
#define PERF_LOG_ALWAYS(level, cat, x)
t1
Definition pow22523.h:58
t0
Definition pow22523.h:53
#define true
unsigned int uint32_t
Definition stdint.h:126
unsigned __int64 uint64_t
Definition stdint.h:136