Coverage Report

Created: 2020-02-14 15:38

/src/botan/src/lib/utils/timer.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* (C) 2018 Jack Lloyd
3
*
4
* Botan is released under the Simplified BSD License (see license.txt)
5
*/
6
7
#include <botan/internal/timer.h>
8
#include <botan/internal/os_utils.h>
9
#include <algorithm>
10
#include <sstream>
11
#include <iomanip>
12
13
namespace Botan {
14
15
void Timer::start()
16
0
   {
17
0
   stop();
18
0
   m_timer_start = OS::get_system_timestamp_ns();
19
0
   m_cpu_cycles_start = OS::get_cpu_cycle_counter();
20
0
   }
21
22
void Timer::stop()
23
0
   {
24
0
   if(m_timer_start)
25
0
      {
26
0
      if(m_cpu_cycles_start != 0)
27
0
         {
28
0
         const uint64_t cycles_taken = OS::get_cpu_cycle_counter() - m_cpu_cycles_start;
29
0
         if(cycles_taken > 0)
30
0
            {
31
0
            m_cpu_cycles_used += static_cast<size_t>(cycles_taken * m_clock_cycle_ratio);
32
0
            }
33
0
         }
34
0
35
0
      const uint64_t now = OS::get_system_timestamp_ns();
36
0
37
0
      if(now > m_timer_start)
38
0
         {
39
0
         const uint64_t dur = now - m_timer_start;
40
0
41
0
         m_time_used += dur;
42
0
43
0
         if(m_event_count == 0)
44
0
            {
45
0
            m_min_time = m_max_time = dur;
46
0
            }
47
0
         else
48
0
            {
49
0
            m_max_time = std::max(m_max_time, dur);
50
0
            m_min_time = std::min(m_min_time, dur);
51
0
            }
52
0
         }
53
0
54
0
      m_timer_start = 0;
55
0
      ++m_event_count;
56
0
      }
57
0
   }
58
59
bool Timer::operator<(const Timer& other) const
60
0
   {
61
0
   if(this->doing() != other.doing())
62
0
      return (this->doing() < other.doing());
63
0
64
0
   return (this->get_name() < other.get_name());
65
0
   }
66
67
std::string Timer::to_string() const
68
0
   {
69
0
   if(m_custom_msg.size() > 0)
70
0
      {
71
0
      return m_custom_msg;
72
0
      }
73
0
   else if(this->buf_size() == 0)
74
0
      {
75
0
      return result_string_ops();
76
0
      }
77
0
   else
78
0
      {
79
0
      return result_string_bps();
80
0
      }
81
0
   }
82
83
std::string Timer::result_string_bps() const
84
0
   {
85
0
   const size_t MiB = 1024 * 1024;
86
0
87
0
   const double MiB_total = static_cast<double>(events()) / MiB;
88
0
   const double MiB_per_sec = MiB_total / seconds();
89
0
90
0
   std::ostringstream oss;
91
0
   oss << get_name();
92
0
93
0
   if(!doing().empty())
94
0
      {
95
0
      oss << " " << doing();
96
0
      }
97
0
98
0
   if(buf_size() > 0)
99
0
      {
100
0
      oss << " buffer size " << buf_size() << " bytes:";
101
0
      }
102
0
103
0
   if(events() == 0)
104
0
      oss << " " << "N/A";
105
0
   else
106
0
      oss << " " << std::fixed << std::setprecision(3) << MiB_per_sec << " MiB/sec";
107
0
108
0
   if(cycles_consumed() != 0)
109
0
      {
110
0
      const double cycles_per_byte = static_cast<double>(cycles_consumed()) / events();
111
0
      oss << " " << std::fixed << std::setprecision(2) << cycles_per_byte << " cycles/byte";
112
0
      }
113
0
114
0
   oss << " (" << MiB_total << " MiB in " << milliseconds() << " ms)\n";
115
0
116
0
   return oss.str();
117
0
   }
118
119
std::string Timer::result_string_ops() const
120
0
   {
121
0
   std::ostringstream oss;
122
0
123
0
   oss << get_name() << " ";
124
0
125
0
   if(events() == 0)
126
0
      {
127
0
      oss << "no events\n";
128
0
      }
129
0
   else
130
0
      {
131
0
      oss << static_cast<uint64_t>(events_per_second())
132
0
          << ' ' << doing() << "/sec; "
133
0
          << std::setprecision(2) << std::fixed
134
0
          << ms_per_event() << " ms/op";
135
0
136
0
      if(cycles_consumed() != 0)
137
0
         {
138
0
         const double cycles_per_op = static_cast<double>(cycles_consumed()) / events();
139
0
         const size_t precision = (cycles_per_op < 10000) ? 2 : 0;
140
0
         oss << " " << std::fixed << std::setprecision(precision) << cycles_per_op << " cycles/op";
141
0
         }
142
0
143
0
      oss << " (" << events() << " " << (events() == 1 ? "op" : "ops")
144
0
          << " in " << milliseconds() << " ms)\n";
145
0
      }
146
0
147
0
   return oss.str();
148
0
   }
149
150
}