class lowres_clock;
class lowres_system_clock;
-/// \cond internal
-
-class lowres_clock_impl final {
-public:
- using base_steady_clock = std::chrono::steady_clock;
- using base_system_clock = std::chrono::system_clock;
-
- // The clocks' resolutions are 10 ms. However, to make it is easier to do calculations with
- // `std::chrono::milliseconds`, we make the clock period 1 ms instead of 10 ms.
- using period = std::ratio<1, 1000>;
-
- using steady_rep = base_steady_clock::rep;
- using steady_duration = std::chrono::duration<steady_rep, period>;
- using steady_time_point = std::chrono::time_point<lowres_clock, steady_duration>;
-
- using system_rep = base_system_clock::rep;
- using system_duration = std::chrono::duration<system_rep, period>;
- using system_time_point = std::chrono::time_point<lowres_system_clock, system_duration>;
-
- static steady_time_point steady_now() noexcept {
- auto const nr = counters::_steady_now.load(std::memory_order_relaxed);
- return steady_time_point(steady_duration(nr));
- }
-
- static system_time_point system_now() noexcept {
- auto const nr = counters::_system_now.load(std::memory_order_relaxed);
- return system_time_point(system_duration(nr));
- }
-
- // For construction.
- friend class smp;
-private:
- // Both counters are updated by cpu0 and read by other cpus. Place them on their own cache line to avoid false
- // sharing.
- struct alignas(seastar::cache_line_size) counters final {
- static std::atomic<steady_rep> _steady_now;
- static std::atomic<system_rep> _system_now;
- };
-
- // The timer expires every 10 ms.
- static constexpr std::chrono::milliseconds _granularity{10};
-
- // High-resolution timer to drive these low-resolution clocks.
- timer<> _timer{};
-
- static void update() noexcept;
-
- // Private to ensure that static variables are only initialized once.
- // might throw when arming timer.
- lowres_clock_impl();
-};
-
/// \endcond
//
/// \brief Low-resolution and efficient steady clock.
///
-/// This is a monotonic clock with a granularity of 10 ms. Time points from this clock do not correspond to system
+/// This is a monotonic clock with a granularity of ~task_quota. Time points from this clock do not correspond to system
/// time.
///
/// The primary benefit of this clock is that invoking \c now() is inexpensive compared to
///
class lowres_clock final {
public:
- using rep = lowres_clock_impl::steady_rep;
- using period = lowres_clock_impl::period;
- using duration = lowres_clock_impl::steady_duration;
- using time_point = lowres_clock_impl::steady_time_point;
-
+ using rep = std::chrono::steady_clock::rep;
+ using period = std::chrono::steady_clock::period;
+ using duration = std::chrono::steady_clock::duration;
+ using time_point = std::chrono::time_point<lowres_clock, duration>;
static constexpr bool is_steady = true;
-
+private:
+ // Use inline variable to prevent the compiler from introducing an initialization guard
+ inline static thread_local time_point _now;
+public:
///
/// \note Outside of a Seastar application, the result is undefined.
///
static time_point now() noexcept {
- return lowres_clock_impl::steady_now();
+ return _now;
}
+
+ static void update() noexcept;
};
///
///
class lowres_system_clock final {
public:
- using rep = lowres_clock_impl::system_rep;
- using period = lowres_clock_impl::period;
- using duration = lowres_clock_impl::system_duration;
- using time_point = lowres_clock_impl::system_time_point;
-
- static constexpr bool is_steady = lowres_clock_impl::base_system_clock::is_steady;
-
+ using rep = std::chrono::system_clock::rep;
+ using period = std::chrono::system_clock::period;
+ using duration = std::chrono::system_clock::duration;
+ using time_point = std::chrono::time_point<lowres_system_clock, duration>;
+ static constexpr bool is_steady = false;
+private:
+ // Use inline variable to prevent the compiler from introducing an initialization guard
+ inline static thread_local time_point _now;
+ friend class lowres_clock; // for updates
+public:
///
/// \note Outside of a Seastar application, the result is undefined.
///
static time_point now() noexcept {
- return lowres_clock_impl::system_now();
+ return _now;
}
static std::time_t to_time_t(time_point t) noexcept {