/tmp/bitcoin/src/util/time.h
Line | Count | Source |
1 | | // Copyright (c) 2009-2010 Satoshi Nakamoto |
2 | | // Copyright (c) 2009-present The Bitcoin Core developers |
3 | | // Distributed under the MIT software license, see the accompanying |
4 | | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
5 | | |
6 | | #ifndef BITCOIN_UTIL_TIME_H |
7 | | #define BITCOIN_UTIL_TIME_H |
8 | | |
9 | | // The `util/time.h` header is designed to be a drop-in replacement for `chrono`. |
10 | | #include <chrono> // IWYU pragma: export |
11 | | #include <cstdint> |
12 | | #include <ctime> |
13 | | #include <optional> |
14 | | #include <string> |
15 | | #include <string_view> |
16 | | |
17 | | #ifdef WIN32 |
18 | | #include <winsock2.h> |
19 | | #else |
20 | | #include <sys/time.h> |
21 | | #endif |
22 | | |
23 | | using namespace std::chrono_literals; |
24 | | |
25 | | /// Version of the system clock that is mockable in the context of tests (via |
26 | | /// NodeClockContext or ::SetMockTime), otherwise the system clock. |
27 | | struct NodeClock : public std::chrono::system_clock { |
28 | | using time_point = std::chrono::time_point<NodeClock>; |
29 | | /** Return current system time or mocked time, if set */ |
30 | | static time_point now() noexcept; |
31 | | static std::time_t to_time_t(const time_point&) = delete; // unused |
32 | | static time_point from_time_t(std::time_t) = delete; // unused |
33 | | static constexpr time_point epoch{}; |
34 | | }; |
35 | | using NodeSeconds = std::chrono::time_point<NodeClock, std::chrono::seconds>; |
36 | | |
37 | | using SteadyClock = std::chrono::steady_clock; |
38 | | using SteadySeconds = std::chrono::time_point<std::chrono::steady_clock, std::chrono::seconds>; |
39 | | using SteadyMilliseconds = std::chrono::time_point<std::chrono::steady_clock, std::chrono::milliseconds>; |
40 | | using SteadyMicroseconds = std::chrono::time_point<std::chrono::steady_clock, std::chrono::microseconds>; |
41 | | |
42 | | using SystemClock = std::chrono::system_clock; |
43 | | |
44 | | /// Version of SteadyClock that is mockable in the context of tests (via |
45 | | /// SteadyClockContext, or Self::SetMockTime), otherwise the system steady |
46 | | /// clock. |
47 | | struct MockableSteadyClock : public std::chrono::steady_clock { |
48 | | using time_point = std::chrono::time_point<MockableSteadyClock>; |
49 | | |
50 | | using mock_time_point = std::chrono::time_point<MockableSteadyClock, std::chrono::milliseconds>; |
51 | | static constexpr mock_time_point::duration INITIAL_MOCK_TIME{1}; |
52 | | |
53 | | /** Return current system time or mocked time, if set */ |
54 | | static time_point now() noexcept; |
55 | | static std::time_t to_time_t(const time_point&) = delete; // unused |
56 | | static time_point from_time_t(std::time_t) = delete; // unused |
57 | | |
58 | | /** Set mock time for testing. |
59 | | * When mocking the steady clock, start at INITIAL_MOCK_TIME and add durations to elapse time as necessary |
60 | | * for testing. |
61 | | * To stop mocking, call ClearMockTime(). |
62 | | */ |
63 | | static void SetMockTime(mock_time_point::duration mock_time_in); |
64 | | |
65 | | /** Clear mock time, go back to system steady clock. */ |
66 | | static void ClearMockTime(); |
67 | | }; |
68 | | |
69 | | void UninterruptibleSleep(const std::chrono::microseconds& n); |
70 | | |
71 | | /** |
72 | | * Helper to count the seconds of a duration/time_point. |
73 | | * |
74 | | * All durations/time_points should be using std::chrono and calling this should generally |
75 | | * be avoided in code. Though, it is still preferred to an inline t.count() to |
76 | | * protect against a reliance on the exact type of t. |
77 | | * |
78 | | * This helper is used to convert durations/time_points before passing them over an |
79 | | * interface that doesn't support std::chrono (e.g. RPC, debug log, or the GUI) |
80 | | */ |
81 | | template <typename Dur1, typename Dur2> |
82 | | constexpr auto Ticks(Dur2 d) |
83 | 16.5M | { |
84 | 16.5M | return std::chrono::duration_cast<Dur1>(d).count(); |
85 | 16.5M | } auto Ticks<std::chrono::duration<long, std::ratio<1l, 1000000l>>, std::chrono::duration<long, std::ratio<1l, 1000000000l>>>(std::chrono::duration<long, std::ratio<1l, 1000000000l>>) Line | Count | Source | 83 | 5.90M | { | 84 | 5.90M | return std::chrono::duration_cast<Dur1>(d).count(); | 85 | 5.90M | } |
auto Ticks<std::chrono::duration<double, std::ratio<1l, 1000l>>, std::chrono::duration<long, std::ratio<1l, 1000000000l>>>(std::chrono::duration<long, std::ratio<1l, 1000000000l>>) Line | Count | Source | 83 | 3.16M | { | 84 | 3.16M | return std::chrono::duration_cast<Dur1>(d).count(); | 85 | 3.16M | } |
auto Ticks<std::chrono::duration<double, std::ratio<1l, 1l>>, std::chrono::duration<long, std::ratio<1l, 1000000000l>>>(std::chrono::duration<long, std::ratio<1l, 1000000000l>>) Line | Count | Source | 83 | 1.38M | { | 84 | 1.38M | return std::chrono::duration_cast<Dur1>(d).count(); | 85 | 1.38M | } |
auto Ticks<std::chrono::duration<long, std::ratio<1l, 1l>>, std::chrono::duration<long, std::ratio<1l, 1000000000l>>>(std::chrono::duration<long, std::ratio<1l, 1000000000l>>) Line | Count | Source | 83 | 441k | { | 84 | 441k | return std::chrono::duration_cast<Dur1>(d).count(); | 85 | 441k | } |
auto Ticks<std::chrono::duration<double, std::ratio<1l, 1l>>, std::chrono::duration<long, std::ratio<1l, 1l>>>(std::chrono::duration<long, std::ratio<1l, 1l>>) Line | Count | Source | 83 | 4 | { | 84 | 4 | return std::chrono::duration_cast<Dur1>(d).count(); | 85 | 4 | } |
auto Ticks<std::chrono::duration<long, std::ratio<1l, 1000l>>, std::chrono::duration<long, std::ratio<1l, 1000000000l>>>(std::chrono::duration<long, std::ratio<1l, 1000000000l>>) Line | Count | Source | 83 | 4.48k | { | 84 | 4.48k | return std::chrono::duration_cast<Dur1>(d).count(); | 85 | 4.48k | } |
auto Ticks<std::chrono::duration<long, std::ratio<1l, 1l>>, std::chrono::duration<long, std::ratio<1l, 1l>>>(std::chrono::duration<long, std::ratio<1l, 1l>>) Line | Count | Source | 83 | 5.34M | { | 84 | 5.34M | return std::chrono::duration_cast<Dur1>(d).count(); | 85 | 5.34M | } |
auto Ticks<std::chrono::duration<long, std::ratio<1l, 1l>>, std::chrono::duration<long, std::ratio<1l, 1000l>>>(std::chrono::duration<long, std::ratio<1l, 1000l>>) Line | Count | Source | 83 | 6 | { | 84 | 6 | return std::chrono::duration_cast<Dur1>(d).count(); | 85 | 6 | } |
auto Ticks<std::chrono::duration<long, std::ratio<1l, 1l>>, std::chrono::duration<long, std::ratio<3600l, 1l>>>(std::chrono::duration<long, std::ratio<3600l, 1l>>) Line | Count | Source | 83 | 306k | { | 84 | 306k | return std::chrono::duration_cast<Dur1>(d).count(); | 85 | 306k | } |
auto Ticks<std::chrono::duration<long, std::ratio<3600l, 1l>>, std::chrono::duration<long, std::ratio<3600l, 1l>>>(std::chrono::duration<long, std::ratio<3600l, 1l>>) Line | Count | Source | 83 | 1.84k | { | 84 | 1.84k | return std::chrono::duration_cast<Dur1>(d).count(); | 85 | 1.84k | } |
auto Ticks<std::chrono::duration<double, std::ratio<3600l, 1l>>, std::chrono::duration<long, std::ratio<1l, 1l>>>(std::chrono::duration<long, std::ratio<1l, 1l>>) Line | Count | Source | 83 | 618 | { | 84 | 618 | return std::chrono::duration_cast<Dur1>(d).count(); | 85 | 618 | } |
auto Ticks<std::chrono::duration<long, std::ratio<60l, 1l>>, std::chrono::duration<long, std::ratio<60l, 1l>>>(std::chrono::duration<long, std::ratio<60l, 1l>>) Line | Count | Source | 83 | 11 | { | 84 | 11 | return std::chrono::duration_cast<Dur1>(d).count(); | 85 | 11 | } |
|
86 | | |
87 | | template <typename Duration> |
88 | | constexpr int64_t TicksSeconds(Duration d) |
89 | 12 | { |
90 | 12 | return int64_t{Ticks<std::chrono::seconds>(d)}; |
91 | 12 | } long TicksSeconds<std::chrono::duration<long, std::ratio<1l, 1l>>>(std::chrono::duration<long, std::ratio<1l, 1l>>) Line | Count | Source | 89 | 4 | { | 90 | 4 | return int64_t{Ticks<std::chrono::seconds>(d)}; | 91 | 4 | } |
long TicksSeconds<std::chrono::duration<long, std::ratio<1l, 1000l>>>(std::chrono::duration<long, std::ratio<1l, 1000l>>) Line | Count | Source | 89 | 6 | { | 90 | 6 | return int64_t{Ticks<std::chrono::seconds>(d)}; | 91 | 6 | } |
long TicksSeconds<std::chrono::duration<long, std::ratio<1l, 1000000000l>>>(std::chrono::duration<long, std::ratio<1l, 1000000000l>>) Line | Count | Source | 89 | 2 | { | 90 | 2 | return int64_t{Ticks<std::chrono::seconds>(d)}; | 91 | 2 | } |
|
92 | | template <typename Duration, typename Timepoint> |
93 | | constexpr auto TicksSinceEpoch(Timepoint t) |
94 | 5.77M | { |
95 | 5.77M | return Ticks<Duration>(t.time_since_epoch()); |
96 | 5.77M | } auto TicksSinceEpoch<std::chrono::duration<long, std::ratio<1l, 1l>>, std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<1l, 1000000000l>>>>(std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<1l, 1000000000l>>>) Line | Count | Source | 94 | 440k | { | 95 | 440k | return Ticks<Duration>(t.time_since_epoch()); | 96 | 440k | } |
auto TicksSinceEpoch<std::chrono::duration<double, std::ratio<1l, 1l>>, std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<1l, 1l>>>>(std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<1l, 1l>>>) Line | Count | Source | 94 | 4 | { | 95 | 4 | return Ticks<Duration>(t.time_since_epoch()); | 96 | 4 | } |
auto TicksSinceEpoch<std::chrono::duration<long, std::ratio<1l, 1000l>>, std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<1l, 1000000000l>>>>(std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<1l, 1000000000l>>>) Line | Count | Source | 94 | 4 | { | 95 | 4 | return Ticks<Duration>(t.time_since_epoch()); | 96 | 4 | } |
auto TicksSinceEpoch<std::chrono::duration<long, std::ratio<1l, 1l>>, std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<1l, 1l>>>>(std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<1l, 1l>>>) Line | Count | Source | 94 | 98.3k | { | 95 | 98.3k | return Ticks<Duration>(t.time_since_epoch()); | 96 | 98.3k | } |
auto TicksSinceEpoch<std::chrono::duration<long, std::ratio<1l, 1000l>>, std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l>>>>(std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l>>>) Line | Count | Source | 94 | 18 | { | 95 | 18 | return Ticks<Duration>(t.time_since_epoch()); | 96 | 18 | } |
auto TicksSinceEpoch<std::chrono::duration<long, std::ratio<1l, 1l>>, std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1l>>>>(std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1l>>>) Line | Count | Source | 94 | 5.23M | { | 95 | 5.23M | return Ticks<Duration>(t.time_since_epoch()); | 96 | 5.23M | } |
|
97 | 1.18M | constexpr int64_t count_seconds(std::chrono::seconds t) { return t.count(); } |
98 | 315k | constexpr int64_t count_milliseconds(std::chrono::milliseconds t) { return t.count(); } |
99 | 0 | constexpr int64_t count_microseconds(std::chrono::microseconds t) { return t.count(); } |
100 | | |
101 | | using HoursDouble = std::chrono::duration<double, std::chrono::hours::period>; |
102 | | using SecondsDouble = std::chrono::duration<double, std::chrono::seconds::period>; |
103 | | using MillisecondsDouble = std::chrono::duration<double, std::chrono::milliseconds::period>; |
104 | | |
105 | | /** |
106 | | * DEPRECATED |
107 | | * Use either ClockType::now() or Now<TimePointType>() if a cast is needed. |
108 | | * ClockType is |
109 | | * - SteadyClock/std::chrono::steady_clock for steady time |
110 | | * - SystemClock/std::chrono::system_clock for system time |
111 | | * - NodeClock for mockable system time |
112 | | */ |
113 | | int64_t GetTime(); |
114 | | |
115 | | /** |
116 | | * DEPRECATED |
117 | | * Use SetMockTime with chrono type |
118 | | * |
119 | | * @param[in] nMockTimeIn Time in seconds. |
120 | | */ |
121 | | void SetMockTime(int64_t nMockTimeIn); |
122 | | |
123 | | /** For testing. Set e.g. with the setmocktime rpc, or -mocktime argument */ |
124 | | void SetMockTime(std::chrono::seconds mock_time_in); |
125 | | void SetMockTime(std::chrono::time_point<NodeClock, std::chrono::seconds> mock); |
126 | | |
127 | | /** For testing */ |
128 | | std::chrono::seconds GetMockTime(); |
129 | | |
130 | | /** |
131 | | * Return the current time point cast to the given precision. Only use this |
132 | | * when an exact precision is needed, otherwise use T::clock::now() directly. |
133 | | */ |
134 | | template <typename T> |
135 | | T Now() |
136 | 1.56M | { |
137 | 1.56M | return std::chrono::time_point_cast<typename T::duration>(T::clock::now()); |
138 | 1.56M | } std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<1l, 1l>>> Now<std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<1l, 1l>>>>() Line | Count | Source | 136 | 1.10M | { | 137 | 1.10M | return std::chrono::time_point_cast<typename T::duration>(T::clock::now()); | 138 | 1.10M | } |
std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<60l, 1l>>> Now<std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<60l, 1l>>>>() Line | Count | Source | 136 | 1 | { | 137 | 1 | return std::chrono::time_point_cast<typename T::duration>(T::clock::now()); | 138 | 1 | } |
std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<1l, 1000l>>> Now<std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<1l, 1000l>>>>() Line | Count | Source | 136 | 342 | { | 137 | 342 | return std::chrono::time_point_cast<typename T::duration>(T::clock::now()); | 138 | 342 | } |
std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<1l, 1000000l>>> Now<std::chrono::time_point<NodeClock, std::chrono::duration<long, std::ratio<1l, 1000000l>>>>() Line | Count | Source | 136 | 459k | { | 137 | 459k | return std::chrono::time_point_cast<typename T::duration>(T::clock::now()); | 138 | 459k | } |
std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration<long, std::ratio<1l, 1000l>>> Now<std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration<long, std::ratio<1l, 1000l>>>>() Line | Count | Source | 136 | 539 | { | 137 | 539 | return std::chrono::time_point_cast<typename T::duration>(T::clock::now()); | 138 | 539 | } |
|
139 | | /** DEPRECATED, see GetTime */ |
140 | | template <typename T> |
141 | | T GetTime() |
142 | 1.48M | { |
143 | 1.48M | return Now<std::chrono::time_point<NodeClock, T>>().time_since_epoch(); |
144 | 1.48M | } std::chrono::duration<long, std::ratio<1l, 1l>> GetTime<std::chrono::duration<long, std::ratio<1l, 1l>>>() Line | Count | Source | 142 | 1.02M | { | 143 | 1.02M | return Now<std::chrono::time_point<NodeClock, T>>().time_since_epoch(); | 144 | 1.02M | } |
std::chrono::duration<long, std::ratio<60l, 1l>> GetTime<std::chrono::duration<long, std::ratio<60l, 1l>>>() Line | Count | Source | 142 | 1 | { | 143 | 1 | return Now<std::chrono::time_point<NodeClock, T>>().time_since_epoch(); | 144 | 1 | } |
std::chrono::duration<long, std::ratio<1l, 1000l>> GetTime<std::chrono::duration<long, std::ratio<1l, 1000l>>>() Line | Count | Source | 142 | 342 | { | 143 | 342 | return Now<std::chrono::time_point<NodeClock, T>>().time_since_epoch(); | 144 | 342 | } |
std::chrono::duration<long, std::ratio<1l, 1000000l>> GetTime<std::chrono::duration<long, std::ratio<1l, 1000000l>>>() Line | Count | Source | 142 | 459k | { | 143 | 459k | return Now<std::chrono::time_point<NodeClock, T>>().time_since_epoch(); | 144 | 459k | } |
|
145 | | |
146 | | /** |
147 | | * ISO 8601 formatting is preferred. Use the FormatISO8601{DateTime,Date} |
148 | | * helper functions if possible. |
149 | | */ |
150 | | std::string FormatISO8601DateTime(int64_t nTime); |
151 | | std::string FormatISO8601Date(int64_t nTime); |
152 | | std::optional<int64_t> ParseISO8601DateTime(std::string_view str); |
153 | | |
154 | | /** |
155 | | * RFC1123 formatting https://www.rfc-editor.org/rfc/rfc1123#section-5.2.14 |
156 | | * Used in HTTP/1.1 responses |
157 | | */ |
158 | | std::string FormatRFC1123DateTime(int64_t nTime); |
159 | | |
160 | | /** |
161 | | * Convert milliseconds to a struct timeval for e.g. select. |
162 | | */ |
163 | | struct timeval MillisToTimeval(int64_t nTimeout); |
164 | | |
165 | | /** |
166 | | * Convert milliseconds to a struct timeval for e.g. select. |
167 | | */ |
168 | | struct timeval MillisToTimeval(std::chrono::milliseconds ms); |
169 | | |
170 | | #endif // BITCOIN_UTIL_TIME_H |