diff options
author | snaury <snaury@ydb.tech> | 2023-05-16 13:43:28 +0300 |
---|---|---|
committer | snaury <snaury@ydb.tech> | 2023-05-16 13:43:28 +0300 |
commit | c9df7fc86be0b15adc1e812144c41ab5c057baef (patch) | |
tree | 63c809b43d9e026188f6a66725ccac433ba0f734 /library/cpp/time_provider/monotonic.h | |
parent | a2e846788b0a6d372d15ab5de915616cc6bc00ce (diff) | |
download | ydb-c9df7fc86be0b15adc1e812144c41ab5c057baef.tar.gz |
Support monotonic boot time with suspend awareness
Diffstat (limited to 'library/cpp/time_provider/monotonic.h')
-rw-r--r-- | library/cpp/time_provider/monotonic.h | 265 |
1 files changed, 178 insertions, 87 deletions
diff --git a/library/cpp/time_provider/monotonic.h b/library/cpp/time_provider/monotonic.h index e36902d884..9b5e5df149 100644 --- a/library/cpp/time_provider/monotonic.h +++ b/library/cpp/time_provider/monotonic.h @@ -1,111 +1,202 @@ #pragma once #include <util/datetime/base.h> -namespace NMonotonic { -/** - * Returns current monotonic time in microseconds - */ -ui64 GetMonotonicMicroSeconds(); - -/** - * Similar to TInstant, but measuring monotonic time - */ -class TMonotonic: public TTimeBase<TMonotonic> { - using TBase = TTimeBase<TMonotonic>; - -private: - constexpr explicit TMonotonic(TValue value) noexcept - : TBase(value) { - } - -public: - constexpr TMonotonic() noexcept { - } - - static constexpr TMonotonic FromValue(TValue value) noexcept { - return TMonotonic(value); - } - - static inline TMonotonic Now() { - return TMonotonic::MicroSeconds(GetMonotonicMicroSeconds()); - } - using TBase::Days; - using TBase::Hours; - using TBase::MicroSeconds; - using TBase::MilliSeconds; - using TBase::Minutes; - using TBase::Seconds; - - static constexpr TMonotonic Max() noexcept { - return TMonotonic(::Max<ui64>()); - } +namespace NMonotonic { - static constexpr TMonotonic Zero() noexcept { - return TMonotonic(); - } + 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 + */ + ui64 GetMonotonicMicroSeconds(); + + /** + * Similar to TInstant, but measuring monotonic time + */ + class TMonotonic: public TMonotonicBase<TMonotonic> { + using TBase = TMonotonicBase<TMonotonic>; + + protected: + constexpr explicit TMonotonic(TValue value) noexcept + : TBase(value) + { + } + + public: + constexpr TMonotonic() noexcept { + } + + static constexpr TMonotonic FromValue(TValue value) noexcept { + return TMonotonic(value); + } + + static inline TMonotonic Now() { + return TMonotonic::MicroSeconds(GetMonotonicMicroSeconds()); + } + + using TBase::Days; + using TBase::Hours; + using TBase::MicroSeconds; + using TBase::MilliSeconds; + using TBase::Minutes; + using TBase::Seconds; + + template <class T> + inline TMonotonic& operator+=(const T& t) noexcept { + return (*this = (*this + t)); + } + + template <class T> + inline TMonotonic& operator-=(const T& t) noexcept { + return (*this = (*this - t)); + } + }; + + /** + * 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>; + + protected: + constexpr explicit TBootTime(TValue value) noexcept + : TBase(value) + { + } + + public: + constexpr TBootTime() noexcept { + } + + static constexpr TBootTime FromValue(TValue value) noexcept { + return TBootTime(value); + } + + static inline TBootTime Now() { + return TBootTime::MicroSeconds(GetBootTimeMicroSeconds()); + } + + using TBase::Days; + using TBase::Hours; + using TBase::MicroSeconds; + using TBase::MilliSeconds; + using TBase::Minutes; + using TBase::Seconds; + + template <class T> + inline TBootTime& operator+=(const T& t) noexcept { + return (*this = (*this + t)); + } + + template <class T> + inline TBootTime& operator-=(const T& t) noexcept { + return (*this = (*this - t)); + } + }; - static constexpr TMonotonic MicroSeconds(ui64 us) noexcept { - return TMonotonic(TInstant::MicroSeconds(us).GetValue()); - } +} // namespace NMonotonic - static constexpr TMonotonic MilliSeconds(ui64 ms) noexcept { - return TMonotonic(TInstant::MilliSeconds(ms).GetValue()); - } +Y_DECLARE_PODTYPE(NMonotonic::TMonotonic); +Y_DECLARE_PODTYPE(NMonotonic::TBootTime); + +namespace std { + template <> + struct hash<NMonotonic::TMonotonic> { + size_t operator()(const NMonotonic::TMonotonic& key) const noexcept { + 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()); + } + }; +} - static constexpr TMonotonic Seconds(ui64 s) noexcept { - return TMonotonic(TInstant::Seconds(s).GetValue()); - } +namespace NMonotonic { - static constexpr TMonotonic Minutes(ui64 m) noexcept { - return TMonotonic(TInstant::Minutes(m).GetValue()); + constexpr TDuration operator-(const TMonotonic& l, const TMonotonic& r) { + return TInstant::FromValue(l.GetValue()) - TInstant::FromValue(r.GetValue()); } - static constexpr TMonotonic Hours(ui64 h) noexcept { - return TMonotonic(TInstant::Hours(h).GetValue()); + constexpr TMonotonic operator+(const TMonotonic& l, const TDuration& r) { + TInstant result = TInstant::FromValue(l.GetValue()) + r; + return TMonotonic::FromValue(result.GetValue()); } - static constexpr TMonotonic Days(ui64 d) noexcept { - return TMonotonic(TInstant::Days(d).GetValue()); + constexpr TMonotonic operator-(const TMonotonic& l, const TDuration& r) { + TInstant result = TInstant::FromValue(l.GetValue()) - r; + return TMonotonic::FromValue(result.GetValue()); } - template<class T> - inline TMonotonic& operator+=(const T& t) noexcept { - return (*this = (*this + t)); + constexpr TDuration operator-(const TBootTime& l, const TBootTime& r) { + return TInstant::FromValue(l.GetValue()) - TInstant::FromValue(r.GetValue()); } - template<class T> - inline TMonotonic& operator-=(const T& t) noexcept { - return (*this = (*this - t)); + constexpr TBootTime operator+(const TBootTime& l, const TDuration& r) { + TInstant result = TInstant::FromValue(l.GetValue()) + r; + return TBootTime::FromValue(result.GetValue()); } -}; -} // namespace NMonotonic - -Y_DECLARE_PODTYPE(NMonotonic::TMonotonic); -template<> -struct THash<NMonotonic::TMonotonic> { - size_t operator()(const NMonotonic::TMonotonic& key) const { - return THash<NMonotonic::TMonotonic::TValue>()(key.GetValue()); + constexpr TBootTime operator-(const TBootTime& l, const TDuration& r) { + TInstant result = TInstant::FromValue(l.GetValue()) - r; + return TBootTime::FromValue(result.GetValue()); } -}; - -namespace NMonotonic { - -constexpr TDuration operator-(const TMonotonic& l, const TMonotonic& r) { - return TInstant::FromValue(l.GetValue()) - TInstant::FromValue(r.GetValue()); -} - -constexpr TMonotonic operator+(const TMonotonic& l, const TDuration& r) { - TInstant result = TInstant::FromValue(l.GetValue()) + r; - return TMonotonic::FromValue(result.GetValue()); -} - -constexpr TMonotonic operator-(const TMonotonic& l, const TDuration& r) { - TInstant result = TInstant::FromValue(l.GetValue()) - r; - return TMonotonic::FromValue(result.GetValue()); -} } // namespace NMonotonic +// TODO: remove, alias for compatibility using TMonotonic = NMonotonic::TMonotonic; |