v29.4-roots.3 · Commit 2: [PATCH 02/30] 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. The two line-number columns refer to before and after.
src/util/time.cpp
CHANGED
|
@@ -17,6 +17,16 @@
|
|
|
17
17
|
#include <string_view>
|
|
18
18
|
#include <thread>
|
|
19
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
|
+
|
|
20
30
|
void UninterruptibleSleep(const std::chrono::microseconds& n) { std::this_thread::sleep_for(n); }
|
|
21
31
|
|
|
22
32
|
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
126
|
return int64_t{TicksSinceEpoch<std::chrono::seconds>(tp)};
|
|
117
127
|
}
|
|
118
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
|
+
|
|
119
137
|
struct timeval MillisToTimeval(int64_t nTimeout)
|
|
120
138
|
{
|
|
121
139
|
struct timeval timeout;
|
|
@@ -128,3 +146,54 @@ struct timeval MillisToTimeval(std::chrono::milliseconds ms)
|
|
|
128
146
|
{
|
|
129
147
|
return MillisToTimeval(count_milliseconds(ms));
|
|
130
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
|
+
}
|