blob: 5481bd647d16210bc8873feafe10faa7b677f0f3 [file] [log] [blame]
John Park33858a32018-09-28 23:05:48 -07001#ifndef AOS_TIME_H_
2#define AOS_TIME_H_
brians343bc112013-02-10 01:53:46 +00003
Austin Schuh793d6b92016-05-01 13:28:14 -07004#include <chrono>
Tyler Chatowbf0609c2021-07-31 16:13:27 -07005#include <ctime>
Stephan Pleinescd3701f2024-05-30 10:56:04 -07006#include <limits>
Austin Schuh3ce0a922020-07-21 21:08:54 -07007#include <optional>
brians343bc112013-02-10 01:53:46 +00008#include <ostream>
Stephan Pleinescd3701f2024-05-30 10:56:04 -07009#include <string>
10#include <string_view>
11#include <thread> // IWYU pragma: keep
brians343bc112013-02-10 01:53:46 +000012
13namespace aos {
Austin Schuh793d6b92016-05-01 13:28:14 -070014
15class monotonic_clock {
16 public:
17 typedef ::std::chrono::nanoseconds::rep rep;
18 typedef ::std::chrono::nanoseconds::period period;
19 typedef ::std::chrono::nanoseconds duration;
20 typedef ::std::chrono::time_point<monotonic_clock> time_point;
21
22 static monotonic_clock::time_point now() noexcept;
Brian Silvermana3688802019-02-16 19:31:26 -080023 // This clock is still subject to rate adjustments based on adjtime, so it is
24 // not steady.
25 static constexpr bool is_steady = false;
26
Austin Schuh3ce0a922020-07-21 21:08:54 -070027 // Converts the time string to a time_point if it is well formatted. This is
28 // designed to reverse operator <<.
Austin Schuhd90499f2023-03-24 15:10:51 -070029#ifdef __linux__
Austin Schuh3ce0a922020-07-21 21:08:54 -070030 static std::optional<monotonic_clock::time_point> FromString(
31 const std::string_view now);
Austin Schuhd90499f2023-03-24 15:10:51 -070032#endif
Austin Schuh3ce0a922020-07-21 21:08:54 -070033
Brian Silvermana3688802019-02-16 19:31:26 -080034 // Returns the epoch (0).
35 static constexpr monotonic_clock::time_point epoch() {
36 return time_point(zero());
37 }
38
39 static constexpr monotonic_clock::duration zero() { return duration(0); }
40
41 static constexpr time_point min_time{
42 time_point(duration(::std::numeric_limits<duration::rep>::min()))};
Brian Silverman94357272019-02-23 21:00:54 -080043 static constexpr time_point max_time{
44 time_point(duration(::std::numeric_limits<duration::rep>::max()))};
Brian Silvermana3688802019-02-16 19:31:26 -080045};
46
47class realtime_clock {
48 public:
49 typedef ::std::chrono::nanoseconds::rep rep;
50 typedef ::std::chrono::nanoseconds::period period;
51 typedef ::std::chrono::nanoseconds duration;
Austin Schuh40102d22019-12-27 23:30:06 -080052 typedef ::std::chrono::time_point<realtime_clock> time_point;
Brian Silvermana3688802019-02-16 19:31:26 -080053
54#ifdef __linux__
Austin Schuh40102d22019-12-27 23:30:06 -080055 static realtime_clock::time_point now() noexcept;
Brian Silvermana3688802019-02-16 19:31:26 -080056#endif // __linux__
57 static constexpr bool is_steady = false;
Austin Schuh793d6b92016-05-01 13:28:14 -070058
Austin Schuh3ce0a922020-07-21 21:08:54 -070059 // Converts the time string to a time_point if it is well formatted. This is
60 // designed to reverse operator <<.
Austin Schuhd90499f2023-03-24 15:10:51 -070061#ifdef __linux__
Austin Schuh3ce0a922020-07-21 21:08:54 -070062 static std::optional<realtime_clock::time_point> FromString(
63 const std::string_view now);
Austin Schuhd90499f2023-03-24 15:10:51 -070064#endif
Austin Schuh3ce0a922020-07-21 21:08:54 -070065
Austin Schuh793d6b92016-05-01 13:28:14 -070066 // Returns the epoch (0).
Austin Schuh40102d22019-12-27 23:30:06 -080067 static constexpr realtime_clock::time_point epoch() {
Austin Schuh8aec1ed2016-05-01 13:29:20 -070068 return time_point(zero());
Austin Schuh793d6b92016-05-01 13:28:14 -070069 }
Austin Schuh8aec1ed2016-05-01 13:29:20 -070070
Austin Schuh40102d22019-12-27 23:30:06 -080071 static constexpr realtime_clock::duration zero() { return duration(0); }
Austin Schuh858c0212016-11-25 17:23:30 -080072
73 static constexpr time_point min_time{
74 time_point(duration(::std::numeric_limits<duration::rep>::min()))};
Brian Silverman94357272019-02-23 21:00:54 -080075 static constexpr time_point max_time{
76 time_point(duration(::std::numeric_limits<duration::rep>::max()))};
Austin Schuh793d6b92016-05-01 13:28:14 -070077};
78
James Kuszmaul38735e82019-12-07 16:42:06 -080079std::ostream &operator<<(std::ostream &stream,
80 const aos::monotonic_clock::time_point &now);
Austin Schuh40102d22019-12-27 23:30:06 -080081std::ostream &operator<<(std::ostream &stream,
82 const aos::realtime_clock::time_point &now);
Austin Schuhde8a8ff2019-11-30 15:25:36 -080083
Eric Schmiedeberg42273f42023-12-14 13:48:45 -070084std::string ToString(const aos::monotonic_clock::time_point &now);
85std::string ToString(const aos::realtime_clock::time_point &now);
86
brians343bc112013-02-10 01:53:46 +000087namespace time {
Brian Silvermanc03a30c2019-02-16 18:21:56 -080088#ifdef __linux__
89
Austin Schuhf2a50ba2016-12-24 16:16:26 -080090// Construct a time representing the period of hertz.
91constexpr ::std::chrono::nanoseconds FromRate(int hertz) {
92 return ::std::chrono::duration_cast<::std::chrono::nanoseconds>(
93 ::std::chrono::seconds(1)) /
94 hertz;
95}
96
James Kuszmaul651fc3f2019-05-15 21:14:25 -070097template <typename Scalar>
98constexpr Scalar TypedDurationInSeconds(monotonic_clock::duration dt) {
99 return ::std::chrono::duration_cast<::std::chrono::duration<Scalar>>(dt)
100 .count();
101}
102
103constexpr double DurationInSeconds(monotonic_clock::duration dt) {
104 return TypedDurationInSeconds<double>(dt);
105}
106
Brian Silvermanc03a30c2019-02-16 18:21:56 -0800107#endif // __linux__
108
Neil Balch229001a2018-01-07 18:22:52 -0800109// Converts a monotonic_clock::duration into a timespec object.
110struct timespec to_timespec(::aos::monotonic_clock::duration duration);
111
112// Converts a monotonic_clock::time_point into a timespec object as time since
113// epoch.
114struct timespec to_timespec(::aos::monotonic_clock::time_point time);
115
Brian Silverman967e5df2020-02-09 16:43:34 -0800116// Converts a timeval object to a monotonic_clock::time_point.
117::aos::monotonic_clock::time_point from_timeval(struct timeval t);
118
brians343bc112013-02-10 01:53:46 +0000119} // namespace time
120} // namespace aos
121
Brian Silvermanc03a30c2019-02-16 18:21:56 -0800122#ifdef __linux__
123
Alexei Strots08b94232024-05-24 16:48:07 -0700124namespace aos::this_thread {
125void sleep_until(const ::aos::monotonic_clock::time_point &end_time);
126} // namespace aos::this_thread
127
Austin Schuh793d6b92016-05-01 13:28:14 -0700128// Template specialization for monotonic_clock, since we can use clock_nanosleep
129// with TIMER_ABSTIME and get very precise absolute time sleeps.
130template <>
Alexei Strots08b94232024-05-24 16:48:07 -0700131inline void std::this_thread::sleep_until(
132 const ::aos::monotonic_clock::time_point &end_time) {
133 ::aos::this_thread::sleep_until(end_time);
134}
Austin Schuh793d6b92016-05-01 13:28:14 -0700135
Brian Silvermanc03a30c2019-02-16 18:21:56 -0800136#endif // __linux__
Austin Schuh793d6b92016-05-01 13:28:14 -0700137
John Park33858a32018-09-28 23:05:48 -0700138#endif // AOS_TIME_H_