diff options
author | snaury <snaury@ydb.tech> | 2023-05-17 00:09:28 +0300 |
---|---|---|
committer | snaury <snaury@ydb.tech> | 2023-05-17 00:09:28 +0300 |
commit | 56a6dcb981398ed4ff100c1cee255d0737c80ec3 (patch) | |
tree | 5944876280d020cf70fdabc149d704cdeb8694ea /library/cpp/time_provider/monotonic.cpp | |
parent | e95347322acfd16b2fd57c40f30718d6b3e42631 (diff) | |
download | ydb-56a6dcb981398ed4ff100c1cee255d0737c80ec3.tar.gz |
Switch TMonotonic to CLOCK_BOOTTIME instead of a separate type
Diffstat (limited to 'library/cpp/time_provider/monotonic.cpp')
-rw-r--r-- | library/cpp/time_provider/monotonic.cpp | 88 |
1 files changed, 48 insertions, 40 deletions
diff --git a/library/cpp/time_provider/monotonic.cpp b/library/cpp/time_provider/monotonic.cpp index ee0f29e498..f9fb6c5e19 100644 --- a/library/cpp/time_provider/monotonic.cpp +++ b/library/cpp/time_provider/monotonic.cpp @@ -2,9 +2,10 @@ #include <chrono> #include <optional> +#include <system_error> #include <util/system/platform.h> -#ifdef _linux +#ifdef _linux_ #include <time.h> #include <string.h> #endif @@ -12,23 +13,7 @@ namespace NMonotonic { namespace { - // Unfortunately time_since_epoch() is sometimes negative on wine - // Remember initial time point at program start and use offsets from that - std::chrono::steady_clock::time_point MonotonicOffset = std::chrono::steady_clock::now(); - } - - ui64 GetMonotonicMicroSeconds() { - auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now() - MonotonicOffset).count(); - // Steady clock is supposed to never jump backwards, but it's better to be safe in case of buggy implementations - if (Y_UNLIKELY(microseconds < 0)) { - microseconds = 0; - } - // Add one so we never return zero - return microseconds + 1; - } - -#ifdef _linux_ - namespace { +#if defined(_linux_) && defined(CLOCK_BOOTTIME) std::optional<ui64> GetClockBootTimeMicroSeconds() { struct timespec t; std::optional<ui64> r; @@ -37,25 +22,56 @@ namespace NMonotonic { } return r; } +#endif - // We want time relative to process start - std::optional<ui64> BootTimeOffset = GetClockBootTimeMicroSeconds(); - } + struct TMonotonicSupport { +#if defined(_linux_) && defined(CLOCK_BOOTTIME) + // We remember initial offset to measure time relative to program + // start and so we never return a zero time. + std::optional<ui64> BootTimeOffset; +#endif + // Unfortunately time_since_epoch() is sometimes negative on wine + // Remember initial time point at program start and use offsets from that + std::chrono::steady_clock::time_point SteadyClockOffset; - ui64 GetBootTimeMicroSeconds() { - if (Y_UNLIKELY(!BootTimeOffset)) { - return GetMonotonicMicroSeconds(); - } + TMonotonicSupport() { +#if defined(_linux_) && defined(CLOCK_BOOTTIME) + BootTimeOffset = GetClockBootTimeMicroSeconds(); +#endif + SteadyClockOffset = std::chrono::steady_clock::now(); + } - auto r = GetClockBootTimeMicroSeconds(); - Y_VERIFY(r, "Unexpected clock_gettime(CLOCK_BOOTTIME) failure: %s", strerror(errno)); - return *r - *BootTimeOffset + 1; + ui64 GetMicroSeconds() const { +#if defined(_linux_) && defined(CLOCK_BOOTTIME) + if (Y_LIKELY(BootTimeOffset)) { + auto r = GetClockBootTimeMicroSeconds(); + if (Y_UNLIKELY(!r)) { + throw std::system_error( + std::error_code(errno, std::system_category()), + "clock_gettime(CLOCK_BOOTTIME) failed"); + } + // Note: we add 1 so we never return zero + return *r - *BootTimeOffset + 1; + } +#endif + auto elapsed = std::chrono::steady_clock::now() - SteadyClockOffset; + auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count(); + // Steady clock is supposed to never jump backwards, but it's + // better to be safe in case of buggy implementations + if (Y_UNLIKELY(microseconds < 0)) { + microseconds = 0; + } + // Note: we add 1 so we never return zero + return ui64(microseconds) + 1; + } + }; + + TMonotonicSupport MonotonicSupport; } -#else - ui64 GetBootTimeMicroSeconds() { - return GetMonotonicMicroSeconds(); + + ui64 GetMonotonicMicroSeconds() { + return MonotonicSupport.GetMicroSeconds(); } -#endif } @@ -66,11 +82,3 @@ void Out<NMonotonic::TMonotonic>( { o << t - NMonotonic::TMonotonic::Zero(); } - -template <> -void Out<NMonotonic::TBootTime>( - IOutputStream& o, - NMonotonic::TBootTime t) -{ - o << t - NMonotonic::TBootTime::Zero(); -} |