aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorswarmer <swarmer@yandex-team.com>2024-06-06 01:45:47 +0300
committerswarmer <swarmer@yandex-team.com>2024-06-06 01:58:09 +0300
commitf461772a29a6d4d1c1b4890a3c8c9e0384b72769 (patch)
tree41e446cccfe932a96c792b1e7d0422653c6bc70f
parentbcc6b8fc7f29a22c37b867854c71b2b6f85642dd (diff)
downloadydb-f461772a29a6d4d1c1b4890a3c8c9e0384b72769.tar.gz
[util] Better precision of the ProcessUptime on linux
The ProcessUptime function should now usually return a value less than 20 ms if called at the start of the program. 0961a518fdaee4fd243b01c7cf5433dd768897c4
-rw-r--r--util/datetime/process_uptime.cpp12
1 files changed, 9 insertions, 3 deletions
diff --git a/util/datetime/process_uptime.cpp b/util/datetime/process_uptime.cpp
index 7ddf194d9f..3d19850937 100644
--- a/util/datetime/process_uptime.cpp
+++ b/util/datetime/process_uptime.cpp
@@ -32,14 +32,20 @@ TDuration ProcessUptime() {
TUnbufferedFileInput statFile(statPath);
auto statStr = statFile.ReadAll();
const auto completeStatsSize = 20; // First two fields skipped to ignore variations of parentheses
- TVector<TString> stats = StringSplitter(TStringBuf{statStr}.RAfter(')').After(' ')).Split(' ').Take(completeStatsSize);
+ const TVector<TStringBuf> stats = StringSplitter(TStringBuf{statStr}.RAfter(')').After(' ')).Split(' ').Take(completeStatsSize);
ui64 startTimeTicks = 0;
Y_THROW_UNLESS(stats.size() == completeStatsSize, "Broken format of " << statPath);
if (!TryFromString<ui64>(stats.back(), startTimeTicks)) {
ythrow yexception() << "Failed to extract process starttime value from " << statPath;
}
- auto startTimeSeconds = startTimeTicks / sysconf(_SC_CLK_TCK);
- return Uptime() - TDuration::Seconds(startTimeSeconds);
+ long ticksPerSecond = sysconf(_SC_CLK_TCK);
+ Y_THROW_UNLESS_EX(ticksPerSecond != -1, TSystemError() << "Failed to get _SC_CLK_TCK");
+ Y_THROW_UNLESS(ticksPerSecond > 0, "Invalid value of the _SC_CLK_TCK variable: " << ticksPerSecond);
+ const ui64 startTimeSeconds = startTimeTicks / ticksPerSecond;
+ const ui64 fractionTicks = startTimeTicks % ticksPerSecond;
+ const TDuration startTimeFractionSeconds = TDuration::MicroSeconds(1'000'000u * fractionTicks / ticksPerSecond);
+ const TDuration startTime = TDuration::Seconds(startTimeSeconds) + startTimeFractionSeconds;
+ return Uptime() - startTime;
#else
ythrow yexception() << "unimplemented";
#endif