diff options
author | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
---|---|---|
committer | monster <monster@ydb.tech> | 2022-07-07 14:41:37 +0300 |
commit | 06e5c21a835c0e923506c4ff27929f34e00761c2 (patch) | |
tree | 75efcbc6854ef9bd476eb8bf00cc5c900da436a2 /library/cpp/yt/cpu_clock/clock.cpp | |
parent | 03f024c4412e3aa613bb543cf1660176320ba8f4 (diff) | |
download | ydb-06e5c21a835c0e923506c4ff27929f34e00761c2.tar.gz |
fix ya.make
Diffstat (limited to 'library/cpp/yt/cpu_clock/clock.cpp')
-rw-r--r-- | library/cpp/yt/cpu_clock/clock.cpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/library/cpp/yt/cpu_clock/clock.cpp b/library/cpp/yt/cpu_clock/clock.cpp new file mode 100644 index 0000000000..eda3f03bbc --- /dev/null +++ b/library/cpp/yt/cpu_clock/clock.cpp @@ -0,0 +1,102 @@ +#include "clock.h" + +#include <util/system/hp_timer.h> + +#include <library/cpp/yt/assert/assert.h> + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +// Re-calibrate every 1B CPU ticks. +constexpr auto CalibrationCpuPeriod = 1'000'000'000; + +struct TCalibrationState +{ + TCpuInstant CpuInstant; + TInstant Instant; +}; + +double GetMicrosecondsToTicks() +{ + static const auto MicrosecondsToTicks = static_cast<double>(NHPTimer::GetCyclesPerSecond()) / 1'000'000; + return MicrosecondsToTicks; +} + +double GetTicksToMicroseconds() +{ + static const auto TicksToMicroseconds = 1.0 / GetMicrosecondsToTicks(); + return TicksToMicroseconds; +} + +TCalibrationState GetCalibrationState(TCpuInstant cpuInstant) +{ + thread_local TCalibrationState State; + + if (State.CpuInstant + CalibrationCpuPeriod < cpuInstant) { + State.CpuInstant = cpuInstant; + State.Instant = TInstant::Now(); + } + + return State; +} + +TCalibrationState GetCalibrationState() +{ + return GetCalibrationState(GetCpuInstant()); +} + +TDuration CpuDurationToDuration(TCpuDuration cpuDuration, double ticksToMicroseconds) +{ + // TDuration is unsigned and thus does not support negative values. + if (cpuDuration < 0) { + return TDuration::Zero(); + } + return TDuration::MicroSeconds(static_cast<ui64>(cpuDuration * ticksToMicroseconds)); +} + +TCpuDuration DurationToCpuDuration(TDuration duration, double microsecondsToTicks) +{ + return static_cast<TCpuDuration>(duration.MicroSeconds() * microsecondsToTicks); +} + +TInstant GetInstant() +{ + auto cpuInstant = GetCpuInstant(); + auto state = GetCalibrationState(cpuInstant); + YT_ASSERT(cpuInstant >= state.CpuInstant); + return state.Instant + CpuDurationToDuration(cpuInstant - state.CpuInstant, GetTicksToMicroseconds()); +} + +TDuration CpuDurationToDuration(TCpuDuration cpuDuration) +{ + return CpuDurationToDuration(cpuDuration, GetTicksToMicroseconds()); +} + +TCpuDuration DurationToCpuDuration(TDuration duration) +{ + return DurationToCpuDuration(duration, GetMicrosecondsToTicks()); +} + +TInstant CpuInstantToInstant(TCpuInstant cpuInstant) +{ + // TDuration is unsigned and does not support negative values, + // thus we consider two cases separately. + auto state = GetCalibrationState(); + return cpuInstant >= state.CpuInstant + ? state.Instant + CpuDurationToDuration(cpuInstant - state.CpuInstant, GetTicksToMicroseconds()) + : state.Instant - CpuDurationToDuration(state.CpuInstant - cpuInstant, GetTicksToMicroseconds()); +} + +TCpuInstant InstantToCpuInstant(TInstant instant) +{ + // See above. + auto state = GetCalibrationState(); + return instant >= state.Instant + ? state.CpuInstant + DurationToCpuDuration(instant - state.Instant, GetMicrosecondsToTicks()) + : state.CpuInstant - DurationToCpuDuration(state.Instant - instant, GetMicrosecondsToTicks()); +} + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT |