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 | |
parent | e95347322acfd16b2fd57c40f30718d6b3e42631 (diff) | |
download | ydb-56a6dcb981398ed4ff100c1cee255d0737c80ec3.tar.gz |
Switch TMonotonic to CLOCK_BOOTTIME instead of a separate type
Diffstat (limited to 'library/cpp')
-rw-r--r-- | library/cpp/actors/core/monotonic.h | 2 | ||||
-rw-r--r-- | library/cpp/actors/core/monotonic_provider.h | 2 | ||||
-rw-r--r-- | library/cpp/actors/testlib/test_runtime.cpp | 26 | ||||
-rw-r--r-- | library/cpp/actors/testlib/test_runtime.h | 4 | ||||
-rw-r--r-- | library/cpp/time_provider/monotonic.cpp | 88 | ||||
-rw-r--r-- | library/cpp/time_provider/monotonic.h | 134 | ||||
-rw-r--r-- | library/cpp/time_provider/monotonic_provider.cpp | 11 | ||||
-rw-r--r-- | library/cpp/time_provider/monotonic_provider.h | 6 |
8 files changed, 76 insertions, 197 deletions
diff --git a/library/cpp/actors/core/monotonic.h b/library/cpp/actors/core/monotonic.h index 06759ee5ec..2c53785390 100644 --- a/library/cpp/actors/core/monotonic.h +++ b/library/cpp/actors/core/monotonic.h @@ -6,9 +6,7 @@ namespace NActors { using NMonotonic::GetMonotonicMicroSeconds; -using NMonotonic::GetBootTimeMicroSeconds; using TMonotonic = NMonotonic::TMonotonic; -using TBootTime = NMonotonic::TBootTime; } // namespace NActors diff --git a/library/cpp/actors/core/monotonic_provider.h b/library/cpp/actors/core/monotonic_provider.h index ad77c171b9..befe4f7b90 100644 --- a/library/cpp/actors/core/monotonic_provider.h +++ b/library/cpp/actors/core/monotonic_provider.h @@ -5,9 +5,7 @@ namespace NActors { using IMonotonicTimeProvider = NMonotonic::IMonotonicTimeProvider; -using IBootTimeProvider = NMonotonic::IBootTimeProvider; using NMonotonic::CreateDefaultMonotonicTimeProvider; -using NMonotonic::CreateDefaultBootTimeProvider; } // namespace NActors diff --git a/library/cpp/actors/testlib/test_runtime.cpp b/library/cpp/actors/testlib/test_runtime.cpp index 2ec0b27ddc..6fedca1cd2 100644 --- a/library/cpp/actors/testlib/test_runtime.cpp +++ b/library/cpp/actors/testlib/test_runtime.cpp @@ -246,20 +246,6 @@ namespace NActors { TTestActorRuntimeBase& Runtime; }; - class TTestActorRuntimeBase::TBootTimeProvider : public IBootTimeProvider { - public: - TBootTimeProvider(TTestActorRuntimeBase& runtime) - : Runtime(runtime) - { } - - TBootTime Now() override { - return Runtime.GetCurrentBootTime(); - } - - private: - TTestActorRuntimeBase& Runtime; - }; - class TTestActorRuntimeBase::TSchedulerThreadStub : public ISchedulerThread { public: TSchedulerThreadStub(TTestActorRuntimeBase* runtime, TTestActorRuntimeBase::TNodeDataBase* node) @@ -510,7 +496,6 @@ namespace NActors { , RandomProvider(CreateDeterministicRandomProvider(DefaultRandomSeed)) , TimeProvider(new TTimeProvider(*this)) , MonotonicTimeProvider(new TMonotonicTimeProvider(*this)) - , BootTimeProvider(new TBootTimeProvider(*this)) , ShouldContinue() , CurrentTimestamp(0) , DispatchTimeout(DEFAULT_DISPATCH_TIMEOUT) @@ -844,12 +829,6 @@ namespace NActors { return TMonotonic::MicroSeconds(CurrentTimestamp); } - TBootTime TTestActorRuntimeBase::GetCurrentBootTime() const { - TGuard<TMutex> guard(Mutex); - Y_VERIFY(!UseRealThreads); - return TBootTime::MicroSeconds(CurrentTimestamp); - } - void TTestActorRuntimeBase::UpdateCurrentTime(TInstant newTime) { static int counter = 0; ++counter; @@ -881,11 +860,6 @@ namespace NActors { return MonotonicTimeProvider; } - TIntrusivePtr<IBootTimeProvider> TTestActorRuntimeBase::GetBootTimeProvider() { - Y_VERIFY(!UseRealThreads); - return BootTimeProvider; - } - ui32 TTestActorRuntimeBase::GetNodeId(ui32 index) const { Y_VERIFY(index < NodeCount); return FirstNodeId + index; diff --git a/library/cpp/actors/testlib/test_runtime.h b/library/cpp/actors/testlib/test_runtime.h index a5d6b3b6e9..0c1e4207cc 100644 --- a/library/cpp/actors/testlib/test_runtime.h +++ b/library/cpp/actors/testlib/test_runtime.h @@ -190,7 +190,6 @@ namespace NActors { class TExecutorPoolStub; class TTimeProvider; class TMonotonicTimeProvider; - class TBootTimeProvider; enum class EEventAction { PROCESS, @@ -233,10 +232,8 @@ namespace NActors { void SetLogPriority(NActors::NLog::EComponent component, NActors::NLog::EPriority priority); TIntrusivePtr<ITimeProvider> GetTimeProvider(); TIntrusivePtr<IMonotonicTimeProvider> GetMonotonicTimeProvider(); - TIntrusivePtr<IBootTimeProvider> GetBootTimeProvider(); TInstant GetCurrentTime() const; TMonotonic GetCurrentMonotonicTime() const; - TBootTime GetCurrentBootTime() const; void UpdateCurrentTime(TInstant newTime); void AdvanceCurrentTime(TDuration duration); void AddLocalService(const TActorId& actorId, const TActorSetupCmd& cmd, ui32 nodeIndex = 0); @@ -552,7 +549,6 @@ namespace NActors { TIntrusivePtr<IRandomProvider> RandomProvider; TIntrusivePtr<ITimeProvider> TimeProvider; TIntrusivePtr<IMonotonicTimeProvider> MonotonicTimeProvider; - TIntrusivePtr<IBootTimeProvider> BootTimeProvider; protected: struct TNodeDataBase: public TThrRefBase { 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(); -} diff --git a/library/cpp/time_provider/monotonic.h b/library/cpp/time_provider/monotonic.h index 9b5e5df149..a1258e3342 100644 --- a/library/cpp/time_provider/monotonic.h +++ b/library/cpp/time_provider/monotonic.h @@ -4,63 +4,22 @@ namespace NMonotonic { - template <class TDerived> - class TMonotonicBase: public TTimeBase<TDerived> { - using TBase = TTimeBase<TDerived>; - - public: - using TBase::TBase; - - using TBase::Days; - using TBase::Hours; - using TBase::MicroSeconds; - using TBase::MilliSeconds; - using TBase::Minutes; - using TBase::Seconds; - - static constexpr TDerived Max() noexcept { - return TDerived::FromValue(::Max<ui64>()); - } - - static constexpr TDerived Zero() noexcept { - return TDerived::FromValue(0); - } - - static constexpr TDerived MicroSeconds(ui64 us) noexcept { - return TDerived::FromValue(TInstant::MicroSeconds(us).GetValue()); - } - - static constexpr TDerived MilliSeconds(ui64 ms) noexcept { - return TDerived::FromValue(TInstant::MilliSeconds(ms).GetValue()); - } - - static constexpr TDerived Seconds(ui64 s) noexcept { - return TDerived::FromValue(TInstant::Seconds(s).GetValue()); - } - - static constexpr TDerived Minutes(ui64 m) noexcept { - return TDerived::FromValue(TInstant::Minutes(m).GetValue()); - } - - static constexpr TDerived Hours(ui64 h) noexcept { - return TDerived::FromValue(TInstant::Hours(h).GetValue()); - } - - static constexpr TDerived Days(ui64 d) noexcept { - return TDerived::FromValue(TInstant::Days(d).GetValue()); - } - }; - /** * Returns current monotonic time in microseconds + * + * On Linux uses CLOCK_BOOTTIME under the hood, so it includes time passed + * during suspend and makes it safe for measuring lease times. */ ui64 GetMonotonicMicroSeconds(); /** * Similar to TInstant, but measuring monotonic time + * + * On Linux uses CLOCK_BOOTTIME under the hood, so it includes time passed + * during suspend and makes it safe for measuring lease times. */ - class TMonotonic: public TMonotonicBase<TMonotonic> { - using TBase = TMonotonicBase<TMonotonic>; + class TMonotonic: public TTimeBase<TMonotonic> { + using TBase = TTimeBase<TMonotonic>; protected: constexpr explicit TMonotonic(TValue value) noexcept @@ -87,60 +46,45 @@ namespace NMonotonic { using TBase::Minutes; using TBase::Seconds; - template <class T> - inline TMonotonic& operator+=(const T& t) noexcept { - return (*this = (*this + t)); + static constexpr TMonotonic Max() noexcept { + return TMonotonic::FromValue(::Max<ui64>()); } - template <class T> - inline TMonotonic& operator-=(const T& t) noexcept { - return (*this = (*this - t)); + static constexpr TMonotonic Zero() noexcept { + return TMonotonic::FromValue(0); } - }; - /** - * Returns current CLOCK_BOOTTIME time in microseconds - */ - ui64 GetBootTimeMicroSeconds(); - - /** - * Similar to TInstant, but measuring CLOCK_BOOTTIME time - */ - class TBootTime: public TMonotonicBase<TBootTime> { - using TBase = TMonotonicBase<TBootTime>; + static constexpr TMonotonic MicroSeconds(ui64 us) noexcept { + return TMonotonic::FromValue(TInstant::MicroSeconds(us).GetValue()); + } - protected: - constexpr explicit TBootTime(TValue value) noexcept - : TBase(value) - { + static constexpr TMonotonic MilliSeconds(ui64 ms) noexcept { + return TMonotonic::FromValue(TInstant::MilliSeconds(ms).GetValue()); } - public: - constexpr TBootTime() noexcept { + static constexpr TMonotonic Seconds(ui64 s) noexcept { + return TMonotonic::FromValue(TInstant::Seconds(s).GetValue()); } - static constexpr TBootTime FromValue(TValue value) noexcept { - return TBootTime(value); + static constexpr TMonotonic Minutes(ui64 m) noexcept { + return TMonotonic::FromValue(TInstant::Minutes(m).GetValue()); } - static inline TBootTime Now() { - return TBootTime::MicroSeconds(GetBootTimeMicroSeconds()); + static constexpr TMonotonic Hours(ui64 h) noexcept { + return TMonotonic::FromValue(TInstant::Hours(h).GetValue()); } - using TBase::Days; - using TBase::Hours; - using TBase::MicroSeconds; - using TBase::MilliSeconds; - using TBase::Minutes; - using TBase::Seconds; + static constexpr TMonotonic Days(ui64 d) noexcept { + return TMonotonic::FromValue(TInstant::Days(d).GetValue()); + } template <class T> - inline TBootTime& operator+=(const T& t) noexcept { + inline TMonotonic& operator+=(const T& t) noexcept { return (*this = (*this + t)); } template <class T> - inline TBootTime& operator-=(const T& t) noexcept { + inline TMonotonic& operator-=(const T& t) noexcept { return (*this = (*this - t)); } }; @@ -148,7 +92,6 @@ namespace NMonotonic { } // namespace NMonotonic Y_DECLARE_PODTYPE(NMonotonic::TMonotonic); -Y_DECLARE_PODTYPE(NMonotonic::TBootTime); namespace std { template <> @@ -157,13 +100,6 @@ namespace std { return hash<NMonotonic::TMonotonic::TValue>()(key.GetValue()); } }; - - template <> - struct hash<NMonotonic::TBootTime> { - size_t operator()(const NMonotonic::TBootTime& key) const noexcept { - return hash<NMonotonic::TBootTime::TValue>()(key.GetValue()); - } - }; } namespace NMonotonic { @@ -182,20 +118,6 @@ namespace NMonotonic { return TMonotonic::FromValue(result.GetValue()); } - constexpr TDuration operator-(const TBootTime& l, const TBootTime& r) { - return TInstant::FromValue(l.GetValue()) - TInstant::FromValue(r.GetValue()); - } - - constexpr TBootTime operator+(const TBootTime& l, const TDuration& r) { - TInstant result = TInstant::FromValue(l.GetValue()) + r; - return TBootTime::FromValue(result.GetValue()); - } - - constexpr TBootTime operator-(const TBootTime& l, const TDuration& r) { - TInstant result = TInstant::FromValue(l.GetValue()) - r; - return TBootTime::FromValue(result.GetValue()); - } - } // namespace NMonotonic // TODO: remove, alias for compatibility diff --git a/library/cpp/time_provider/monotonic_provider.cpp b/library/cpp/time_provider/monotonic_provider.cpp index cc9297213a..6b116a0e73 100644 --- a/library/cpp/time_provider/monotonic_provider.cpp +++ b/library/cpp/time_provider/monotonic_provider.cpp @@ -29,15 +29,4 @@ namespace NMonotonic { return TIntrusivePtr<IMonotonicTimeProvider>(new TDefaultMonotonicTimeProvider); } - class TDefaultBootTimeProvider: public IBootTimeProvider { - public: - TBootTime Now() override { - return TBootTime::Now(); - } - }; - - TIntrusivePtr<IBootTimeProvider> CreateDefaultBootTimeProvider() { - return TIntrusivePtr<IBootTimeProvider>(new TDefaultBootTimeProvider); - } - } diff --git a/library/cpp/time_provider/monotonic_provider.h b/library/cpp/time_provider/monotonic_provider.h index 49f2835490..17b57e4075 100644 --- a/library/cpp/time_provider/monotonic_provider.h +++ b/library/cpp/time_provider/monotonic_provider.h @@ -10,11 +10,6 @@ namespace NMonotonic { virtual TMonotonic Now() = 0; }; - class IBootTimeProvider: public TThrRefBase { - public: - virtual TBootTime Now() = 0; - }; - class TMonotonicOperator { public: static void RegisterProvider(TIntrusivePtr<IMonotonicTimeProvider> provider); @@ -22,7 +17,6 @@ namespace NMonotonic { }; TIntrusivePtr<IMonotonicTimeProvider> CreateDefaultMonotonicTimeProvider(); - TIntrusivePtr<IBootTimeProvider> CreateDefaultBootTimeProvider(); } |