diff options
author | Jack Lloyd <[email protected]> | 2018-09-04 20:22:54 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-09-10 13:27:44 -0400 |
commit | 5dd295583fabccf6656e714636596f3c3cb02abd (patch) | |
tree | 05ec5ea9eafff293ad596d4b5e733c8fe99051b0 /src/lib/utils/timer.h | |
parent | 36ccdb28dacf78b91821dcf5167d425be25550d6 (diff) |
Promote Timer to an internal util class
Diffstat (limited to 'src/lib/utils/timer.h')
-rw-r--r-- | src/lib/utils/timer.h | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/src/lib/utils/timer.h b/src/lib/utils/timer.h new file mode 100644 index 000000000..6a6b807db --- /dev/null +++ b/src/lib/utils/timer.h @@ -0,0 +1,216 @@ +/* +* (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 <botan/internal/os_utils.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, size_t buf_size = 0) : + Timer(name, "", "", 1, buf_size, 0.0, 0.0) + {} + + Timer(const Timer& other) = default; + + static uint64_t get_system_timestamp_ns() + { + return Botan::OS::get_system_timestamp_ns(); + } + + static uint64_t get_cpu_cycle_counter() + { + return Botan::OS::get_processor_timestamp(); + } + + void start() + { + stop(); + m_timer_start = Timer::get_system_timestamp_ns(); + m_cpu_cycles_start = Timer::get_cpu_cycle_counter(); + } + + 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<double>(m_clock_speed) * value()) / 1000; + } + 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 + { + if(this->doing() != other.doing()) + return (this->doing() < other.doing()); + + return (this->get_name() < other.get_name()); + } + + std::string to_string() const + { + if(m_custom_msg.size() > 0) + { + return m_custom_msg; + } + else if(this->buf_size() == 0) + { + return result_string_ops(); + } + else + { + return result_string_bps(); + } + } + + 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 |