aboutsummaryrefslogtreecommitdiffstats
path: root/util/datetime
diff options
context:
space:
mode:
authorDaniil Cherednik <dan.cherednik@gmail.com>2022-09-21 20:17:38 +0300
committerDaniil Cherednik <dan.cherednik@gmail.com>2022-09-21 20:17:38 +0300
commite6c9b17192c56494adba359d5e132c431b241191 (patch)
tree6f2449871a118a0e8919ce842b1174e06cb470ef /util/datetime
parent285021ab1aac39e84b269d9bacd4deee69cf63fc (diff)
downloadydb-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.cpp17
-rw-r--r--util/datetime/cputimer.h4
-rw-r--r--util/datetime/cputimer_ut.cpp10
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());
+ }
+}