Source code

Revision control

Copy as Markdown

Other Tools

/*
* (C) 2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_TIMER_H_
#define BOTAN_TIMER_H_
#include <botan/types.h>
#include <string>
#include <chrono>
namespace Botan {
class BOTAN_TEST_API Timer final
{
public:
Timer(const std::string& name,
const std::string& provider,
const std::string& doing,
uint64_t event_mult,
size_t buf_size,
double clock_cycle_ratio,
uint64_t clock_speed)
: m_name(name + ((provider.empty() || provider == "base") ? "" : " [" + provider + "]"))
, m_doing(doing)
, m_buf_size(buf_size)
, m_event_mult(event_mult)
, m_clock_cycle_ratio(clock_cycle_ratio)
, m_clock_speed(clock_speed)
{}
Timer(const std::string& name) :
Timer(name, "", "", 1, 0, 0.0, 0)
{}
Timer(const std::string& name, size_t buf_size) :
Timer(name, "", "", buf_size, buf_size, 0.0, 0)
{}
Timer(const Timer& other) = default;
Timer& operator=(const Timer& other) = default;
void start();
void stop();
bool under(std::chrono::milliseconds msec)
{
return (milliseconds() < msec.count());
}
class Timer_Scope final
{
public:
explicit Timer_Scope(Timer& timer)
: m_timer(timer)
{
m_timer.start();
}
~Timer_Scope()
{
try
{
m_timer.stop();
}
catch(...) {}
}
private:
Timer& m_timer;
};
template<typename F>
auto run(F f) -> decltype(f())
{
Timer_Scope timer(*this);
return f();
}
template<typename F>
void run_until_elapsed(std::chrono::milliseconds msec, F f)
{
while(this->under(msec))
{
run(f);
}
}
uint64_t value() const
{
return m_time_used;
}
double seconds() const
{
return milliseconds() / 1000.0;
}
double milliseconds() const
{
return value() / 1000000.0;
}
double ms_per_event() const
{
return milliseconds() / events();
}
uint64_t cycles_consumed() const
{
if(m_clock_speed != 0)
{
return static_cast<uint64_t>((m_clock_speed * value()) / 1000.0);
}
return m_cpu_cycles_used;
}
uint64_t events() const
{
return m_event_count * m_event_mult;
}
const std::string& get_name() const
{
return m_name;
}
const std::string& doing() const
{
return m_doing;
}
size_t buf_size() const
{
return m_buf_size;
}
double bytes_per_second() const
{
return seconds() > 0.0 ? events() / seconds() : 0.0;
}
double events_per_second() const
{
return seconds() > 0.0 ? events() / seconds() : 0.0;
}
double seconds_per_event() const
{
return events() > 0 ? seconds() / events() : 0.0;
}
void set_custom_msg(const std::string& s)
{
m_custom_msg = s;
}
bool operator<(const Timer& other) const;
std::string to_string() const;
private:
std::string result_string_bps() const;
std::string result_string_ops() const;
// const data
std::string m_name, m_doing;
size_t m_buf_size;
uint64_t m_event_mult;
double m_clock_cycle_ratio;
uint64_t m_clock_speed;
// set at runtime
std::string m_custom_msg;
uint64_t m_time_used = 0, m_timer_start = 0;
uint64_t m_event_count = 0;
uint64_t m_max_time = 0, m_min_time = 0;
uint64_t m_cpu_cycles_start = 0, m_cpu_cycles_used = 0;
};
}
#endif