Skip to content
Bitcoin Roots

v30.3-roots.1 · Commit 2: [PATCH 02/68] feat(runtime): preserve Roots operator controls on Core 30.3

src/util/time.cpp

Before: src/util/time.cpp · After: src/util/time.cpp

File metadata
index 68af84a8fccdd8ffc8d8964446742e68a3dab849..9a9c436e16df80e0df288fc0a0e888f315a0699d 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
@@ -117,6 +127,14 @@ std::optional<int64_t> ParseISO8601DateTime(std::string_view str)
117
127
  return int64_t{TicksSinceEpoch<std::chrono::seconds>(tp)};
118
128
  }
119
129
 
130
+ std::string FormatISO8601Time(int64_t nTime)
131
+ {
132
+ const std::chrono::sys_seconds secs{std::chrono::seconds{nTime}};
133
+ const auto days{std::chrono::floor<std::chrono::days>(secs)};
134
+ const std::chrono::hh_mm_ss hms{secs - days};
135
+ return strprintf("%02i:%02i:%02iZ", hms.hours().count(), hms.minutes().count(), hms.seconds().count());
136
+ }
137
+
120
138
  struct timeval MillisToTimeval(int64_t nTimeout)
121
139
  {
122
140
  struct timeval timeout;
@@ -129,3 +147,54 @@ struct timeval MillisToTimeval(std::chrono::milliseconds ms)
129
147
  {
130
148
  return MillisToTimeval(count_milliseconds(ms));
131
149
  }
150
+
151
+ std::chrono::nanoseconds ThreadCpuTime()
152
+ {
153
+ #ifdef CLOCK_THREAD_CPUTIME_ID
154
+ timespec t;
155
+ if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t) == -1) {
156
+ return std::chrono::nanoseconds{0};
157
+ }
158
+ return std::chrono::seconds{t.tv_sec} + std::chrono::nanoseconds{t.tv_nsec};
159
+ #elif defined(WIN32)
160
+ FILETIME creation;
161
+ FILETIME exit;
162
+ FILETIME kernel;
163
+ FILETIME user;
164
+ // GetThreadTimes():
165
+ // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreadtimes
166
+ if (GetThreadTimes(GetCurrentThread(), &creation, &exit, &kernel, &user) == 0) {
167
+ return std::chrono::nanoseconds{0};
168
+ }
169
+
170
+ // https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
171
+ // "... you should copy the low- and high-order parts of the file time to a
172
+ // ULARGE_INTEGER structure, perform 64-bit arithmetic on the QuadPart
173
+ // member ..."
174
+
175
+ ULARGE_INTEGER kernel_;
176
+ kernel_.LowPart = kernel.dwLowDateTime;
177
+ kernel_.HighPart = kernel.dwHighDateTime;
178
+
179
+ ULARGE_INTEGER user_;
180
+ user_.LowPart = user.dwLowDateTime;
181
+ user_.HighPart = user.dwHighDateTime;
182
+
183
+ // The units of the returned values from GetThreadTimes() are "100-nanosecond periods".
184
+ // So, we multiply by 100 to get nanoseconds.
185
+ return std::chrono::nanoseconds{(kernel_.QuadPart + user_.QuadPart) * 100};
186
+ #else
187
+ return std::chrono::nanoseconds{0};
188
+ #endif
189
+ }
190
+
191
+ std::chrono::nanoseconds operator+=(std::atomic<std::chrono::nanoseconds>& a, std::chrono::nanoseconds b)
192
+ {
193
+ std::chrono::nanoseconds expected;
194
+ std::chrono::nanoseconds desired;
195
+ do {
196
+ expected = a.load();
197
+ desired = expected + b;
198
+ } while (!a.compare_exchange_weak(expected, desired));
199
+ return desired;
200
+ }