diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2022-09-21 20:17:38 +0300 |
---|---|---|
committer | Daniil Cherednik <dan.cherednik@gmail.com> | 2022-09-21 20:17:38 +0300 |
commit | e6c9b17192c56494adba359d5e132c431b241191 (patch) | |
tree | 6f2449871a118a0e8919ce842b1174e06cb470ef /util/datetime | |
parent | 285021ab1aac39e84b269d9bacd4deee69cf63fc (diff) | |
download | ydb-e6c9b17192c56494adba359d5e132c431b241191.tar.gz |
Ydb stable 22-4-2122.4.21
x-stable-origin-commit: e89099581237299a132feafb5b58af59ebd0468a
Diffstat (limited to 'util/datetime')
-rw-r--r-- | util/datetime/cputimer.cpp | 17 | ||||
-rw-r--r-- | util/datetime/cputimer.h | 4 | ||||
-rw-r--r-- | util/datetime/cputimer_ut.cpp | 10 |
3 files changed, 31 insertions, 0 deletions
diff --git a/util/datetime/cputimer.cpp b/util/datetime/cputimer.cpp index a032dbd3df..32ccfd4740 100644 --- a/util/datetime/cputimer.cpp +++ b/util/datetime/cputimer.cpp @@ -49,10 +49,27 @@ TDuration CyclesToDuration(ui64 cycles) { return TDuration::MicroSeconds(cycles * 1000000 / GetCyclesPerSecond()); } +TDuration CyclesToDurationSafe(ui64 cycles) +{ + constexpr ui64 cyclesLimit = std::numeric_limits<ui64>::max() / 1000000; + if (cycles <= cyclesLimit) { + return CyclesToDuration(cycles); + } + return TDuration::MicroSeconds(cycles / GetCyclesPerSecond() * 1000000); +} + ui64 DurationToCycles(TDuration duration) { return duration.MicroSeconds() * GetCyclesPerSecond() / 1000000; } +ui64 DurationToCyclesSafe(TDuration duration) +{ + if (duration.MicroSeconds() <= std::numeric_limits<ui64>::max() / GetCyclesPerSecond()) { + return DurationToCycles(duration); + } + return duration.MicroSeconds() / 1000000 * GetCyclesPerSecond(); +} + TPrecisionTimer::TPrecisionTimer() : Start(::GetCycleCount()) { diff --git a/util/datetime/cputimer.h b/util/datetime/cputimer.h index 7d38d5bdb3..b24d6fae8e 100644 --- a/util/datetime/cputimer.h +++ b/util/datetime/cputimer.h @@ -62,6 +62,10 @@ void SetCyclesPerSecond(ui64 cycles); TDuration CyclesToDuration(ui64 cycles); ui64 DurationToCycles(TDuration duration); +// NBS-3400 - CyclesToDuration and DurationToCycles may overflow for long running events +TDuration CyclesToDurationSafe(ui64 cycles); +ui64 DurationToCyclesSafe(TDuration duration); + class TPrecisionTimer { private: ui64 Start = 0; diff --git a/util/datetime/cputimer_ut.cpp b/util/datetime/cputimer_ut.cpp new file mode 100644 index 0000000000..21a657d5c7 --- /dev/null +++ b/util/datetime/cputimer_ut.cpp @@ -0,0 +1,10 @@ +#include <library/cpp/testing/unittest/registar.h> + +#include "cputimer.h" + +Y_UNIT_TEST_SUITE(TestCpuTimerSuite) { + Y_UNIT_TEST(TestCyclesToDurationSafe) { + ui64 cycles = DurationToCyclesSafe(TDuration::Hours(24)); + UNIT_ASSERT_VALUES_EQUAL(24, CyclesToDurationSafe(cycles).Hours()); + } +} |