0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-11 14:38:57 +02:00

ircd::util: Improvements to timer tool; fix accumulator semantics; comments.

This commit is contained in:
Jason Volk 2020-09-10 11:42:53 -07:00
parent f51ffb1530
commit 407202f85f
2 changed files with 82 additions and 30 deletions

View file

@ -17,19 +17,46 @@ inline namespace util
struct timer;
}}
/// Stopwatch w/ accumulation.
///
/// This utility can be used to gauge the duration of something. The clock
/// is started by default upon construction. Users can query the running time
/// using the at(), or using the pretty() convenience.
///
/// This timer features an accumulator state so the clock can be stopped and
/// continued, and each time the accumulator is updated. The accumulator
/// value is always added into results: when the timer is stopped, the result
/// is simply the accumulator value; when the clock is running, the result is
/// the accumulator value added to the difference of the current time and the
/// last start time.
///
/// One can instantiate the timer without starting the clock with the `nostart`
/// overload. Additionally, a lambda constructor will accumulate the time it
/// takes to execute the provided function.
struct ircd::util::timer
{
IRCD_OVERLOAD(nostart)
using clock = std::chrono::steady_clock;
IRCD_OVERLOAD(nostart)
nanoseconds accumulator {0ns};
clock::time_point start {clock::now()};
nanoseconds accumulator
{
0ns
};
clock::time_point start
{
clock::now()
};
// Observers
bool stopped() const;
template<class duration = std::chrono::seconds> duration get() const;
template<class duration = std::chrono::seconds> duration at() const;
// Convenience wrapper for util::pretty()
string_view pretty(const mutable_buffer &out, const int &fmt = 0) const;
std::string pretty(const int &fmt = 0) const;
// Control
void cont();
void stop();
@ -40,23 +67,40 @@ struct ircd::util::timer
inline
ircd::util::timer::timer(nostart_t)
:start{clock::time_point::min()}
:start
{
clock::time_point::min()
}
{}
template<class duration>
duration
inline duration
ircd::util::timer::at()
const
{
const auto now(clock::now());
return duration_cast<duration>(now - start);
const auto now
{
!stopped()?
clock::now():
start
};
const auto elapsed
{
duration_cast<decltype(accumulator)>(now - start)
};
const auto accumulator
{
this->accumulator + elapsed
};
return duration_cast<duration>(accumulator);
}
template<class duration>
duration
ircd::util::timer::get()
inline bool
ircd::util::timer::stopped()
const
{
return std::chrono::duration_cast<duration>(accumulator);
return start == clock::time_point::min();
}

View file

@ -283,31 +283,46 @@ ircd::util::timer::timer(const std::function<void ()> &func)
void
ircd::util::timer::stop()
{
if(stopped())
return;
const auto now
{
!stopped()?
clock::now():
start
};
const auto now(clock::now());
accumulator += std::chrono::duration_cast<decltype(accumulator)>(now - start);
const auto elapsed
{
duration_cast<decltype(accumulator)>(now - start)
};
accumulator += elapsed;
start = clock::time_point::min();
}
void
ircd::util::timer::cont()
{
if(!stopped())
const auto now
{
const auto now(clock::now());
accumulator += std::chrono::duration_cast<decltype(accumulator)>(now - start);
}
clock::now()
};
start = clock::now();
const auto elapsed
{
!stopped()?
duration_cast<decltype(accumulator)>(now - start):
decltype(accumulator)(0)
};
accumulator += elapsed;
start = now;
}
std::string
ircd::util::timer::pretty(const int &fmt)
const
{
return util::pretty(at(), fmt);
return util::pretty(at<nanoseconds>(), fmt);
}
ircd::string_view
@ -315,14 +330,7 @@ ircd::util::timer::pretty(const mutable_buffer &out,
const int &fmt)
const
{
return util::pretty(out, at(), fmt);
}
bool
ircd::util::timer::stopped()
const
{
return start == clock::time_point::min();
return util::pretty(out, at<nanoseconds>(), fmt);
}
///////////////////////////////////////////////////////////////////////////////