diff options
author | ivanmorozov <ivanmorozov@yandex-team.com> | 2022-11-29 15:52:07 +0300 |
---|---|---|
committer | ivanmorozov <ivanmorozov@yandex-team.com> | 2022-11-29 15:52:07 +0300 |
commit | 8ff1738e8665e5c3a1a328104806bcafbc1bd7ae (patch) | |
tree | 9657e2ea4d923a22e69e954fe11fb77e35bc3271 | |
parent | db99cf88226de50e47bd3acdc0ecfe634ce1d828 (diff) | |
download | ydb-8ff1738e8665e5c3a1a328104806bcafbc1bd7ae.tar.gz |
time providers in separated library for future refactoring
-rw-r--r-- | library/cpp/actors/core/CMakeLists.txt | 1 | ||||
-rw-r--r-- | library/cpp/actors/core/monotonic.cpp | 28 | ||||
-rw-r--r-- | library/cpp/actors/core/monotonic.h | 106 | ||||
-rw-r--r-- | library/cpp/actors/core/monotonic_provider.cpp | 11 | ||||
-rw-r--r-- | library/cpp/actors/core/monotonic_provider.h | 7 | ||||
-rw-r--r-- | library/cpp/neh/asio/io_service_impl.h | 14 | ||||
-rw-r--r-- | library/cpp/time_provider/CMakeLists.txt | 2 | ||||
-rw-r--r-- | library/cpp/time_provider/monotonic.cpp | 31 | ||||
-rw-r--r-- | library/cpp/time_provider/monotonic.h | 111 | ||||
-rw-r--r-- | library/cpp/time_provider/monotonic_provider.cpp | 32 | ||||
-rw-r--r-- | library/cpp/time_provider/monotonic_provider.h | 21 | ||||
-rw-r--r-- | library/cpp/time_provider/time_provider.cpp | 16 | ||||
-rw-r--r-- | library/cpp/time_provider/time_provider.h | 5 |
13 files changed, 243 insertions, 142 deletions
diff --git a/library/cpp/actors/core/CMakeLists.txt b/library/cpp/actors/core/CMakeLists.txt index ee3cc95991..c1c8d82623 100644 --- a/library/cpp/actors/core/CMakeLists.txt +++ b/library/cpp/actors/core/CMakeLists.txt @@ -22,6 +22,7 @@ target_link_libraries(cpp-actors-core PUBLIC library-cpp-lwtrace cpp-monlib-dynamic_counters library-cpp-svnversion + library-cpp-time_provider cpp-threading-future ) target_sources(cpp-actors-core PRIVATE diff --git a/library/cpp/actors/core/monotonic.cpp b/library/cpp/actors/core/monotonic.cpp index cff9111ee3..4d2c28ef0c 100644 --- a/library/cpp/actors/core/monotonic.cpp +++ b/library/cpp/actors/core/monotonic.cpp @@ -1,31 +1,9 @@ #include "monotonic.h" -#include <chrono> - namespace NActors { - 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; - } +ui64 GetMonotonicMicroSeconds() { + return NMonotonic::GetMonotonicMicroSeconds(); +} } // namespace NActors - -template<> -void Out<NActors::TMonotonic>( - IOutputStream& o, - NActors::TMonotonic t) -{ - o << t - NActors::TMonotonic::Zero(); -} diff --git a/library/cpp/actors/core/monotonic.h b/library/cpp/actors/core/monotonic.h index 6fceb91dbe..46fd13f335 100644 --- a/library/cpp/actors/core/monotonic.h +++ b/library/cpp/actors/core/monotonic.h @@ -1,111 +1,11 @@ #pragma once #include <util/datetime/base.h> +#include <library/cpp/time_provider/monotonic.h> namespace NActors { - /** - * 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>()); - } - - static constexpr TMonotonic Zero() noexcept { - return TMonotonic(); - } - - static constexpr TMonotonic MicroSeconds(ui64 us) noexcept { - return TMonotonic(TInstant::MicroSeconds(us).GetValue()); - } - - static constexpr TMonotonic MilliSeconds(ui64 ms) noexcept { - return TMonotonic(TInstant::MilliSeconds(ms).GetValue()); - } - - static constexpr TMonotonic Seconds(ui64 s) noexcept { - return TMonotonic(TInstant::Seconds(s).GetValue()); - } - - static constexpr TMonotonic Minutes(ui64 m) noexcept { - return TMonotonic(TInstant::Minutes(m).GetValue()); - } - - static constexpr TMonotonic Hours(ui64 h) noexcept { - return TMonotonic(TInstant::Hours(h).GetValue()); - } - - static constexpr TMonotonic Days(ui64 d) noexcept { - return TMonotonic(TInstant::Days(d).GetValue()); - } - - 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)); - } - }; -} // namespace NActors - -Y_DECLARE_PODTYPE(NActors::TMonotonic); - -template<> -struct THash<NActors::TMonotonic> { - size_t operator()(const NActors::TMonotonic& key) const { - return THash<NActors::TMonotonic::TValue>()(key.GetValue()); - } -}; - -namespace NActors { - - 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()); - } +ui64 GetMonotonicMicroSeconds(); +using TMonotonic = NMonotonic::TMonotonic; } // namespace NActors diff --git a/library/cpp/actors/core/monotonic_provider.cpp b/library/cpp/actors/core/monotonic_provider.cpp index fb3b656da6..9e5bb1aadf 100644 --- a/library/cpp/actors/core/monotonic_provider.cpp +++ b/library/cpp/actors/core/monotonic_provider.cpp @@ -2,15 +2,8 @@ namespace NActors { -class TDefaultMonotonicTimeProvider : public IMonotonicTimeProvider { -public: - TMonotonic Now() override { - return TMonotonic::Now(); - } -}; - -TIntrusivePtr<IMonotonicTimeProvider> CreateDefaultMonotonicTimeProvider() { - return TIntrusivePtr<IMonotonicTimeProvider>(new TDefaultMonotonicTimeProvider); +TIntrusivePtr<NActors::IMonotonicTimeProvider> CreateDefaultMonotonicTimeProvider() { + return NMonotonic::CreateDefaultMonotonicTimeProvider(); } } // namespace NActors diff --git a/library/cpp/actors/core/monotonic_provider.h b/library/cpp/actors/core/monotonic_provider.h index 98e1203400..1f6c44aeb9 100644 --- a/library/cpp/actors/core/monotonic_provider.h +++ b/library/cpp/actors/core/monotonic_provider.h @@ -1,13 +1,10 @@ #pragma once -#include "monotonic.h" +#include <library/cpp/time_provider/monotonic_provider.h> namespace NActors { -class IMonotonicTimeProvider : public TThrRefBase { -public: - virtual TMonotonic Now() = 0; -}; +using IMonotonicTimeProvider = ::IMonotonicTimeProvider; TIntrusivePtr<IMonotonicTimeProvider> CreateDefaultMonotonicTimeProvider(); diff --git a/library/cpp/neh/asio/io_service_impl.h b/library/cpp/neh/asio/io_service_impl.h index 46fa9f9ee1..687b5576e8 100644 --- a/library/cpp/neh/asio/io_service_impl.h +++ b/library/cpp/neh/asio/io_service_impl.h @@ -21,6 +21,19 @@ #endif namespace NAsio { +#if defined(_arm_) + template <typename T> + struct TLockFreeSequence { + Y_NO_INLINE T& Get(size_t n) { + with_lock (M) { + return H[n]; + } + } + + TMutex M; + THashMap<size_t, T> H; + }; +#else //TODO: copypaste from neh, - need fix template <class T> class TLockFreeSequence { @@ -59,6 +72,7 @@ namespace NAsio { private: T* volatile T_[sizeof(size_t) * 8]; }; +#endif struct TOperationCompare { template <class T> diff --git a/library/cpp/time_provider/CMakeLists.txt b/library/cpp/time_provider/CMakeLists.txt index aa7435c882..eecbe5cf32 100644 --- a/library/cpp/time_provider/CMakeLists.txt +++ b/library/cpp/time_provider/CMakeLists.txt @@ -13,5 +13,7 @@ target_link_libraries(library-cpp-time_provider PUBLIC yutil ) target_sources(library-cpp-time_provider PRIVATE + ${CMAKE_SOURCE_DIR}/library/cpp/time_provider/monotonic.cpp ${CMAKE_SOURCE_DIR}/library/cpp/time_provider/time_provider.cpp + ${CMAKE_SOURCE_DIR}/library/cpp/time_provider/monotonic_provider.cpp ) diff --git a/library/cpp/time_provider/monotonic.cpp b/library/cpp/time_provider/monotonic.cpp new file mode 100644 index 0000000000..99126080e2 --- /dev/null +++ b/library/cpp/time_provider/monotonic.cpp @@ -0,0 +1,31 @@ +#include "monotonic.h" + +#include <chrono> + +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; +} + +} // namespace TMonotonic + +template<> +void Out<NMonotonic::TMonotonic>( + IOutputStream& o, + NMonotonic::TMonotonic t) +{ + o << t - NMonotonic::TMonotonic::Zero(); +} diff --git a/library/cpp/time_provider/monotonic.h b/library/cpp/time_provider/monotonic.h new file mode 100644 index 0000000000..e36902d884 --- /dev/null +++ b/library/cpp/time_provider/monotonic.h @@ -0,0 +1,111 @@ +#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>()); + } + + static constexpr TMonotonic Zero() noexcept { + return TMonotonic(); + } + + static constexpr TMonotonic MicroSeconds(ui64 us) noexcept { + return TMonotonic(TInstant::MicroSeconds(us).GetValue()); + } + + static constexpr TMonotonic MilliSeconds(ui64 ms) noexcept { + return TMonotonic(TInstant::MilliSeconds(ms).GetValue()); + } + + static constexpr TMonotonic Seconds(ui64 s) noexcept { + return TMonotonic(TInstant::Seconds(s).GetValue()); + } + + static constexpr TMonotonic Minutes(ui64 m) noexcept { + return TMonotonic(TInstant::Minutes(m).GetValue()); + } + + static constexpr TMonotonic Hours(ui64 h) noexcept { + return TMonotonic(TInstant::Hours(h).GetValue()); + } + + static constexpr TMonotonic Days(ui64 d) noexcept { + return TMonotonic(TInstant::Days(d).GetValue()); + } + + 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)); + } +}; +} // 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()); + } +}; + +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 + +using TMonotonic = NMonotonic::TMonotonic; diff --git a/library/cpp/time_provider/monotonic_provider.cpp b/library/cpp/time_provider/monotonic_provider.cpp new file mode 100644 index 0000000000..22937bd873 --- /dev/null +++ b/library/cpp/time_provider/monotonic_provider.cpp @@ -0,0 +1,32 @@ +#include "monotonic_provider.h" + +namespace { +TIntrusivePtr<IMonotonicTimeProvider> GlobalMonotonicTimeProvider; +} + +void TMonotonicOperator::RegisterProvider(TIntrusivePtr<IMonotonicTimeProvider> provider) { + GlobalMonotonicTimeProvider = provider; +} + +NMonotonic::TMonotonic TMonotonicOperator::Now() { + if (GlobalMonotonicTimeProvider) { + return GlobalMonotonicTimeProvider->Now(); + } else { + return TMonotonic::Now(); + } +} + +namespace NMonotonic { + +class TDefaultMonotonicTimeProvider: public IMonotonicTimeProvider { +public: + TMonotonic Now() override { + return TMonotonic::Now(); + } +}; + +TIntrusivePtr<IMonotonicTimeProvider> CreateDefaultMonotonicTimeProvider() { + return TIntrusivePtr<IMonotonicTimeProvider>(new TDefaultMonotonicTimeProvider); +} + +} diff --git a/library/cpp/time_provider/monotonic_provider.h b/library/cpp/time_provider/monotonic_provider.h new file mode 100644 index 0000000000..966e2e496b --- /dev/null +++ b/library/cpp/time_provider/monotonic_provider.h @@ -0,0 +1,21 @@ +#pragma once + +#include <util/datetime/base.h> +#include "monotonic.h" + +class IMonotonicTimeProvider: public TThrRefBase { +public: + virtual TMonotonic Now() = 0; +}; + +class TMonotonicOperator { +public: + static void RegisterProvider(TIntrusivePtr<IMonotonicTimeProvider> provider); + static TMonotonic Now(); +}; + +namespace NMonotonic { + +TIntrusivePtr<IMonotonicTimeProvider> CreateDefaultMonotonicTimeProvider(); + +} diff --git a/library/cpp/time_provider/time_provider.cpp b/library/cpp/time_provider/time_provider.cpp index 6c1ba8e07c..687681f1ff 100644 --- a/library/cpp/time_provider/time_provider.cpp +++ b/library/cpp/time_provider/time_provider.cpp @@ -28,3 +28,19 @@ TIntrusivePtr<ITimeProvider> CreateDefaultTimeProvider() { TIntrusivePtr<ITimeProvider> CreateDeterministicTimeProvider(ui64 seed) { return TIntrusivePtr<ITimeProvider>(new TDeterministicTimeProvider(seed)); } + +namespace { +TIntrusivePtr<ITimeProvider> GlobalTimeProvider; +} + +void TInstantOperator::RegisterProvider(TIntrusivePtr<ITimeProvider> provider) { + GlobalTimeProvider = provider; +} + +TInstant TInstantOperator::Now() { + if (!GlobalTimeProvider) { + return TInstant::Now(); + } else { + return GlobalTimeProvider->Now(); + } +} diff --git a/library/cpp/time_provider/time_provider.h b/library/cpp/time_provider/time_provider.h index 46e0a885da..6744e027bd 100644 --- a/library/cpp/time_provider/time_provider.h +++ b/library/cpp/time_provider/time_provider.h @@ -7,5 +7,10 @@ public: virtual TInstant Now() = 0; }; +class TInstantOperator { + static void RegisterProvider(TIntrusivePtr<ITimeProvider> provider); + static TInstant Now(); +}; + TIntrusivePtr<ITimeProvider> CreateDefaultTimeProvider(); TIntrusivePtr<ITimeProvider> CreateDeterministicTimeProvider(ui64 seed); |