Skip to content
Bitcoin Roots

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. 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
+ }