quill
StopWatch.h
1 
7 #pragma once
8 
9 #include <chrono>
10 #include <cstdint>
11 
12 #include "quill/DeferredFormatCodec.h"
13 #include "quill/backend/RdtscClock.h"
14 #include "quill/core/Attributes.h"
15 #include "quill/core/ChronoTimeUtils.h"
16 #include "quill/core/Common.h"
17 #include "quill/core/Rdtsc.h"
18 
19 #include "quill/bundled/fmt/format.h"
20 #include "quill/std/Chrono.h"
21 
22 QUILL_BEGIN_NAMESPACE
23 
24 namespace detail
25 {
44 template <ClockSourceType ClockType>
45 class StopWatch
46 {
47 public:
48  static_assert((ClockType == ClockSourceType::Tsc) || (ClockType == ClockSourceType::System),
49  "Invalid ClockType");
50 
55  {
56  if constexpr (ClockType == ClockSourceType::Tsc)
57  {
58  _ns_per_tick = RdtscClock::RdtscTicks::instance().ns_per_tick();
59  _start_tp = rdtsc();
60  }
61  else
62  {
63  _start_tp = detail::get_timestamp_ns<std::chrono::steady_clock>();
64  }
65  }
66 
71  [[nodiscard]] std::chrono::duration<double> elapsed() const
72  {
73  return elapsed_as<std::chrono::duration<double>>();
74  }
75 
80  template <typename T>
81  [[nodiscard]] T elapsed_as() const
82  {
83  if constexpr (ClockType == ClockSourceType::Tsc)
84  {
85  return std::chrono::duration_cast<T>(std::chrono::nanoseconds{
86  static_cast<uint64_t>(static_cast<double>(rdtsc() - _start_tp) * _ns_per_tick)});
87  }
88  else
89  {
90  return std::chrono::duration_cast<T>(
91  std::chrono::nanoseconds{detail::get_timestamp_ns<std::chrono::steady_clock>() - _start_tp});
92  }
93  }
94 
98  void reset()
99  {
100  if constexpr (ClockType == ClockSourceType::Tsc)
101  {
102  _start_tp = rdtsc();
103  }
104  else
105  {
106  _start_tp = detail::get_timestamp_ns<std::chrono::steady_clock>();
107  }
108  }
109 
110 private:
111  double _ns_per_tick{0};
112  uint64_t _start_tp{0};
113 };
114 } // namespace detail
115 
120 
125 
126 QUILL_END_NAMESPACE
127 
128 template <quill::ClockSourceType ClockType>
129 struct quill::Codec<quill::detail::StopWatch<ClockType>>
130  : quill::DeferredFormatCodec<quill::detail::StopWatch<ClockType>>
131 {
132 };
133 
134 template <quill::ClockSourceType ClockType>
135 struct fmtquill::formatter<quill::detail::StopWatch<ClockType>> : fmtquill::formatter<double>
136 {
137  template <typename FormatContext>
138  auto format(quill::detail::StopWatch<ClockType> const& sw, FormatContext& ctx) const
139  -> decltype(ctx.out())
140  {
141  return fmtquill::formatter<double>::format(sw.elapsed().count(), ctx);
142  }
143 };
StopWatch()
Constructor.
Definition: StopWatch.h:54
Definition: DocTestExtensions.cpp:27
Setups a signal handler to handle fatal signals.
Definition: BackendManager.h:24
std::chrono::duration< double > elapsed() const
Returns the elapsed time since construction.
Definition: StopWatch.h:71
QUILL_NODISCARD QUILL_ATTRIBUTE_HOT uint64_t rdtsc() noexcept
Get the TSC counter.
Definition: Rdtsc.h:109
T elapsed_as() const
Returns the elapsed time since construction as the specified duration type.
Definition: StopWatch.h:81
void reset()
Resets the stopwatch, starting the measurement from the current time.
Definition: StopWatch.h:98
A stopwatch utility for measuring elapsed time since construction.
Definition: StopWatch.h:45