aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/time_provider/monotonic.h
diff options
context:
space:
mode:
authorsnaury <snaury@ydb.tech>2023-05-16 13:43:28 +0300
committersnaury <snaury@ydb.tech>2023-05-16 13:43:28 +0300
commitc9df7fc86be0b15adc1e812144c41ab5c057baef (patch)
tree63c809b43d9e026188f6a66725ccac433ba0f734 /library/cpp/time_provider/monotonic.h
parenta2e846788b0a6d372d15ab5de915616cc6bc00ce (diff)
downloadydb-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.h265
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;