diff options
author | swarmer <swarmer@yandex-team.com> | 2024-06-06 01:45:47 +0300 |
---|---|---|
committer | swarmer <swarmer@yandex-team.com> | 2024-06-06 01:58:09 +0300 |
commit | f461772a29a6d4d1c1b4890a3c8c9e0384b72769 (patch) | |
tree | 41e446cccfe932a96c792b1e7d0422653c6bc70f | |
parent | bcc6b8fc7f29a22c37b867854c71b2b6f85642dd (diff) | |
download | ydb-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.cpp | 12 |
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 |