Skip to content

Commit e08a3fe

Browse files
committed
Make timer_t use microseconds and make it restartable
We can use the timer in more places if we have better resolution. For places where we don't need the resolution it doesn't matter because it will just get rounded. While we are at it we also use microseconds in the thread_pool code so that we use the same unit everywhere. The timer is restartable now, by repeatedly calling start/stop() we can add up the times. Also we are trying, as much as possible, to keep to the time types supplied by chrono. This gives us automatic correct time output with the fmt library which knows about those types. And it should make time conversions easier.
1 parent 5c6d7df commit e08a3fe

File tree

7 files changed

+41
-39
lines changed

7 files changed

+41
-39
lines changed

src/flex-table.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ class table_connection_t
237237
return *m_proj;
238238
}
239239

240-
void task_set(std::future<std::chrono::milliseconds> &&future)
240+
void task_set(std::future<std::chrono::microseconds> &&future)
241241
{
242242
m_task_result.set(std::move(future));
243243
}

src/middle-pgsql.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,12 @@ struct middle_pgsql_t : public middle_t
122122
std::string m_prepare_fw_dep_lookups;
123123
std::string m_create_fw_dep_indexes;
124124

125-
void task_set(std::future<std::chrono::milliseconds> &&future)
125+
void task_set(std::future<std::chrono::microseconds> &&future)
126126
{
127127
m_task_result.set(std::move(future));
128128
}
129129

130-
std::chrono::milliseconds task_wait() { return m_task_result.wait(); }
130+
std::chrono::microseconds task_wait() { return m_task_result.wait(); }
131131

132132
private:
133133
std::shared_ptr<db_target_descr_t> m_copy_target;

src/table.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class table_t
4343

4444
void sync();
4545

46-
void task_set(std::future<std::chrono::milliseconds> &&future)
46+
void task_set(std::future<std::chrono::microseconds> &&future)
4747
{
4848
m_task_result.set(std::move(future));
4949
}

src/thread-pool.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414
#include <cassert>
1515
#include <string>
1616

17-
std::chrono::milliseconds task_result_t::wait()
17+
std::chrono::microseconds task_result_t::wait()
1818
{
1919
if (m_future.valid()) {
2020
m_result = m_future.get();
2121

2222
// Make sure the result is not 0 so it is different than
2323
// "no result yet".
24-
if (m_result == std::chrono::milliseconds::zero()) {
24+
if (m_result == std::chrono::microseconds::zero()) {
2525
++m_result;
2626
}
2727
}

src/thread-pool.hpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*/
2020

2121
#include "logging.hpp"
22+
#include "util.hpp"
2223

2324
#include <osmium/thread/function_wrapper.hpp>
2425
#include <osmium/thread/queue.hpp>
@@ -41,7 +42,7 @@ class task_result_t
4142
* Initialize this result with the future obtained from the
4243
* thread_pool_t::submit() function.
4344
*/
44-
void set(std::future<std::chrono::milliseconds> &&future)
45+
void set(std::future<std::chrono::microseconds> &&future)
4546
{
4647
m_future = std::move(future);
4748
}
@@ -52,17 +53,17 @@ class task_result_t
5253
* \return The runtime of the task.
5354
* \throws Any exception the task has thrown.
5455
*/
55-
std::chrono::milliseconds wait();
56+
std::chrono::microseconds wait();
5657

5758
/**
5859
* Return the run-time of this task. Will be 0 if the task has not
5960
* yet finished or >0 if the task has finished.
6061
*/
61-
std::chrono::milliseconds runtime() const noexcept { return m_result; }
62+
std::chrono::microseconds runtime() const noexcept { return m_result; }
6263

6364
private:
64-
std::future<std::chrono::milliseconds> m_future{};
65-
std::chrono::milliseconds m_result{};
65+
std::future<std::chrono::microseconds> m_future{};
66+
std::chrono::microseconds m_result{};
6667
}; // class task_result_t
6768

6869
/**
@@ -96,23 +97,21 @@ class thread_pool_t
9697
* of the task can be queried.
9798
*/
9899
template <typename TFunction>
99-
std::future<std::chrono::milliseconds> submit(TFunction &&func)
100+
std::future<std::chrono::microseconds> submit(TFunction &&func)
100101
{
101-
std::packaged_task<std::chrono::milliseconds()> task{
102+
std::packaged_task<std::chrono::microseconds()> task{
102103
[f = std::forward<TFunction>(func)]() {
103104
log_debug("Starting task...");
104-
auto const start_time = std::chrono::steady_clock::now();
105+
util::timer_t timer;
105106
f();
106-
auto const end_time = std::chrono::steady_clock::now();
107-
auto const run_time =
108-
std::chrono::duration_cast<std::chrono::milliseconds>(
109-
end_time - start_time);
107+
timer.stop();
108+
log_debug("Done task in {}.",
109+
std::chrono::duration_cast<std::chrono::milliseconds>(
110+
timer.elapsed()));
110111

111-
log_debug("Done task in {}.", run_time);
112-
113-
return run_time;
112+
return timer.elapsed();
114113
}};
115-
std::future<std::chrono::milliseconds> future_result{task.get_future()};
114+
std::future<std::chrono::microseconds> future_result{task.get_future()};
116115
m_work_queue.push(std::move(task));
117116

118117
return future_result;

src/util.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,10 @@ std::string human_readable_duration(uint64_t seconds)
4848
return "{}s ({}h {}m {}s)"_format(seconds, mins / 60, mins % 60, secs);
4949
}
5050

51-
std::string human_readable_duration(std::chrono::milliseconds ms)
51+
std::string human_readable_duration(std::chrono::microseconds duration)
5252
{
5353
return human_readable_duration(static_cast<uint64_t>(
54-
std::chrono::duration_cast<std::chrono::seconds>(ms).count()));
54+
std::chrono::duration_cast<std::chrono::seconds>(duration).count()));
5555
}
5656

5757
std::string get_password()

src/util.hpp

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,26 +83,26 @@ class string_id_list_t
8383
}; // class string_id_list_t
8484

8585
/**
86-
* Helper class for timing with a granularity of seconds. The timer will
87-
* start on construction and is stopped by calling stop().
86+
* Helper class for timing with a granularity of microseconds. The timer will
87+
* start on construction or it can be started by calling start(). It is stopped
88+
* by calling stop(). Timer can be restarted and times will be added up.
8889
*/
8990
class timer_t
9091
{
9192
public:
92-
timer_t() noexcept : m_start(std::time(nullptr)) {}
93+
timer_t() noexcept : m_start(clock::now()) {}
94+
95+
void start() noexcept { m_start = clock::now(); }
9396

9497
/// Stop timer and return elapsed time
95-
uint64_t stop() noexcept
98+
std::chrono::microseconds stop() noexcept
9699
{
97-
m_stop = std::time(nullptr);
98-
return static_cast<uint64_t>(m_stop - m_start);
100+
m_duration += std::chrono::duration_cast<std::chrono::microseconds>(
101+
clock::now() - m_start);
102+
return m_duration;
99103
}
100104

101-
/// Return elapsed time
102-
uint64_t elapsed() const noexcept
103-
{
104-
return static_cast<uint64_t>(m_stop - m_start);
105-
}
105+
std::chrono::microseconds elapsed() const noexcept { return m_duration; }
106106

107107
/**
108108
* Calculate ratio: value divided by elapsed time.
@@ -111,22 +111,25 @@ class timer_t
111111
*/
112112
double per_second(double value) const noexcept
113113
{
114-
auto const seconds = elapsed();
114+
auto const seconds =
115+
std::chrono::duration_cast<std::chrono::seconds>(m_duration)
116+
.count();
115117
if (seconds == 0) {
116118
return 0.0;
117119
}
118120
return value / static_cast<double>(seconds);
119121
}
120122

121123
private:
122-
std::time_t m_start;
123-
std::time_t m_stop = 0;
124+
using clock = std::chrono::steady_clock;
125+
std::chrono::time_point<clock> m_start;
126+
std::chrono::microseconds m_duration{};
124127

125128
}; // class timer_t
126129

127130
std::string human_readable_duration(uint64_t seconds);
128131

129-
std::string human_readable_duration(std::chrono::milliseconds ms);
132+
std::string human_readable_duration(std::chrono::microseconds duration);
130133

131134
std::string get_password();
132135

0 commit comments

Comments
 (0)