v29.4-roots.4 · Commit 2: [PATCH 02/37] runtime: preserve shared operator controls
src/util/time.cpp
Before: src/util/time.cpp · After: src/util/time.cpp
File metadata
index cafc27e0d059193d645865efd13cad83ec98b2d8..c5b24a52c102843cb4ce89fb8fe072f967fcfc04 100644
Download original patch · Release notes
Diff rows 1–84 of 84. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.
src/util/time.cpp
CHANGED
|
@@ -17,6 +17,16 @@
|
|
| 17 |
#include <string_view>
|
| 18 |
#include <thread>
|
| 19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
void UninterruptibleSleep(const std::chrono::microseconds& n) { std::this_thread::sleep_for(n); }
|
| 21 |
|
| 22 |
static std::atomic<std::chrono::seconds> g_mock_time{}; //!< For testing
|
|
@@ -116,6 +126,14 @@ std::optional<int64_t> ParseISO8601DateTime(std::string_view str)
|
|
| 116 |
return int64_t{TicksSinceEpoch<std::chrono::seconds>(tp)};
|
| 117 |
}
|
| 118 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
struct timeval MillisToTimeval(int64_t nTimeout)
|
| 120 |
{
|
| 121 |
struct timeval timeout;
|
|
@@ -128,3 +146,54 @@ struct timeval MillisToTimeval(std::chrono::milliseconds ms)
|
|
| 128 |
{
|
| 129 |
return MillisToTimeval(count_milliseconds(ms));
|
| 130 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
#include <string_view>
|
| 18 |
#include <thread>
|
| 19 |
|
| 20 |
+
#ifdef WIN32
|
| 21 |
+
#include <windows.h>
|
| 22 |
+
#include <winnt.h>
|
| 23 |
+
|
| 24 |
+
#include <processthreadsapi.h>
|
| 25 |
+
#else
|
| 26 |
+
#include <ctime>
|
| 27 |
+
#endif
|
| 28 |
+
|
| 29 |
+
|
| 30 |
void UninterruptibleSleep(const std::chrono::microseconds& n) { std::this_thread::sleep_for(n); }
|
| 31 |
|
| 32 |
static std::atomic<std::chrono::seconds> g_mock_time{}; //!< For testing
|
|
|
|
| 126 |
return int64_t{TicksSinceEpoch<std::chrono::seconds>(tp)};
|
| 127 |
}
|
| 128 |
|
| 129 |
+
std::string FormatISO8601Time(int64_t nTime)
|
| 130 |
+
{
|
| 131 |
+
const std::chrono::sys_seconds secs{std::chrono::seconds{nTime}};
|
| 132 |
+
const auto days{std::chrono::floor<std::chrono::days>(secs)};
|
| 133 |
+
const std::chrono::hh_mm_ss hms{secs - days};
|
| 134 |
+
return strprintf("%02i:%02i:%02iZ", hms.hours().count(), hms.minutes().count(), hms.seconds().count());
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
struct timeval MillisToTimeval(int64_t nTimeout)
|
| 138 |
{
|
| 139 |
struct timeval timeout;
|
|
|
|
| 146 |
{
|
| 147 |
return MillisToTimeval(count_milliseconds(ms));
|
| 148 |
}
|
| 149 |
+
|
| 150 |
+
std::chrono::nanoseconds ThreadCpuTime()
|
| 151 |
+
{
|
| 152 |
+
#ifdef CLOCK_THREAD_CPUTIME_ID
|
| 153 |
+
timespec t;
|
| 154 |
+
if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t) == -1) {
|
| 155 |
+
return std::chrono::nanoseconds{0};
|
| 156 |
+
}
|
| 157 |
+
return std::chrono::seconds{t.tv_sec} + std::chrono::nanoseconds{t.tv_nsec};
|
| 158 |
+
#elif defined(WIN32)
|
| 159 |
+
FILETIME creation;
|
| 160 |
+
FILETIME exit;
|
| 161 |
+
FILETIME kernel;
|
| 162 |
+
FILETIME user;
|
| 163 |
+
// GetThreadTimes():
|
| 164 |
+
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreadtimes
|
| 165 |
+
if (GetThreadTimes(GetCurrentThread(), &creation, &exit, &kernel, &user) == 0) {
|
| 166 |
+
return std::chrono::nanoseconds{0};
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
// https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
|
| 170 |
+
// "... you should copy the low- and high-order parts of the file time to a
|
| 171 |
+
// ULARGE_INTEGER structure, perform 64-bit arithmetic on the QuadPart
|
| 172 |
+
// member ..."
|
| 173 |
+
|
| 174 |
+
ULARGE_INTEGER kernel_;
|
| 175 |
+
kernel_.LowPart = kernel.dwLowDateTime;
|
| 176 |
+
kernel_.HighPart = kernel.dwHighDateTime;
|
| 177 |
+
|
| 178 |
+
ULARGE_INTEGER user_;
|
| 179 |
+
user_.LowPart = user.dwLowDateTime;
|
| 180 |
+
user_.HighPart = user.dwHighDateTime;
|
| 181 |
+
|
| 182 |
+
// The units of the returned values from GetThreadTimes() are "100-nanosecond periods".
|
| 183 |
+
// So, we multiply by 100 to get nanoseconds.
|
| 184 |
+
return std::chrono::nanoseconds{(kernel_.QuadPart + user_.QuadPart) * 100};
|
| 185 |
+
#else
|
| 186 |
+
return std::chrono::nanoseconds{0};
|
| 187 |
+
#endif
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
std::chrono::nanoseconds operator+=(std::atomic<std::chrono::nanoseconds>& a, std::chrono::nanoseconds b)
|
| 191 |
+
{
|
| 192 |
+
std::chrono::nanoseconds expected;
|
| 193 |
+
std::chrono::nanoseconds desired;
|
| 194 |
+
do {
|
| 195 |
+
expected = a.load();
|
| 196 |
+
desired = expected + b;
|
| 197 |
+
} while (!a.compare_exchange_weak(expected, desired));
|
| 198 |
+
return desired;
|
| 199 |
+
}
|