blob: dac653341f6834be7f47247d4572d45f6a03fa0d [file] [log] [blame]
Austin Schuh2dc8c7d2021-07-01 17:41:28 -07001#ifndef AOS_EVENTS_LOGGING_BOOT_TIMESTAMP_H_
2#define AOS_EVENTS_LOGGING_BOOT_TIMESTAMP_H_
3
4#include <iostream>
5
6#include "aos/time/time.h"
7
8namespace aos::logger {
9
Austin Schuh66168842021-08-17 19:42:21 -070010// Simple class representing a duration in time and a boot it is from. This
11// gives us something to use for storing the time offset when filtering.
12struct BootDuration {
13 // Boot number for this timestamp.
14 size_t boot = 0u;
15 // Monotonic time in that boot.
16 monotonic_clock::duration duration{0};
17
18 BootDuration operator+(monotonic_clock::duration d) const {
19 return {boot, duration + d};
20 }
21
22 bool operator==(const BootDuration &m2) const {
23 return boot == m2.boot && duration == m2.duration;
24 }
25};
26
Austin Schuh2dc8c7d2021-07-01 17:41:28 -070027// Simple class representing which boot and what monotonic time in that boot.
28// Boots are assumed to be sequential, and the monotonic clock resets on reboot
29// for all the compare operations.
30struct BootTimestamp {
31 // Boot number for this timestamp.
32 size_t boot = 0u;
33 // Monotonic time in that boot.
34 monotonic_clock::time_point time = monotonic_clock::min_time;
35
Austin Schuh66168842021-08-17 19:42:21 -070036 monotonic_clock::duration time_since_epoch() const {
37 return time.time_since_epoch();
38 }
39
Austin Schuh2dc8c7d2021-07-01 17:41:28 -070040 static constexpr BootTimestamp min_time() {
Austin Schuh66168842021-08-17 19:42:21 -070041 return BootTimestamp{.boot = std::numeric_limits<size_t>::min(),
42 .time = monotonic_clock::min_time};
Austin Schuh2dc8c7d2021-07-01 17:41:28 -070043 }
44 static constexpr BootTimestamp max_time() {
45 return BootTimestamp{.boot = std::numeric_limits<size_t>::max(),
46 .time = monotonic_clock::max_time};
47 }
Austin Schuh66168842021-08-17 19:42:21 -070048 static constexpr BootTimestamp epoch() {
49 return BootTimestamp{.boot = 0, .time = monotonic_clock::epoch()};
50 }
Austin Schuh2dc8c7d2021-07-01 17:41:28 -070051
52 // Compare operators. These are implemented such that earlier boots always
53 // compare less than later boots, and the times are only compared in a single
54 // boot.
55 bool operator<(const BootTimestamp &m2) const;
56 bool operator<=(const BootTimestamp &m2) const;
57 bool operator>=(const BootTimestamp &m2) const;
58 bool operator>(const BootTimestamp &m2) const;
59 bool operator==(const BootTimestamp &m2) const;
60 bool operator!=(const BootTimestamp &m2) const;
Austin Schuh66168842021-08-17 19:42:21 -070061
62 BootTimestamp operator+(monotonic_clock::duration d) const {
63 return {boot, time + d};
64 }
65 BootTimestamp operator-(monotonic_clock::duration d) const {
66 return {boot, time - d};
67 }
68 BootTimestamp operator+(BootDuration d) const {
69 return {boot, time + d.duration};
70 }
Austin Schuh2dc8c7d2021-07-01 17:41:28 -070071};
72
Austin Schuh58646e22021-08-23 23:51:46 -070073// Structure to hold both a boot and queue index. Queue indices reset after
74// reboot, so we need to track them.
75struct BootQueueIndex {
76 // Boot number for this queue index.
77 size_t boot = std::numeric_limits<size_t>::max();
78 // Queue index.
79 uint32_t index = std::numeric_limits<uint32_t>::max();
80
81 // Returns a QueueIndex representing an invalid index. Since
82 // std::numeric_limits<uint32_t>::max() is never used in the QueueIndex code
83 // and is reserved as an Invalid value, this will never collide.
84 static BootQueueIndex Invalid() {
85 return {.boot = std::numeric_limits<size_t>::max(),
86 .index = std::numeric_limits<uint32_t>::max()};
87 }
88
89 bool operator==(const BootQueueIndex &b2) const {
90 return index == b2.index && boot == b2.boot;
91 }
92 bool operator!=(const BootQueueIndex &b2) const {
93 return index != b2.index || boot != b2.boot;
94 }
95 bool operator<(const BootQueueIndex &b2) const {
96 if (boot == b2.boot) {
97 return index < b2.index;
98 }
99 return boot < b2.boot;
100 }
101 bool operator>(const BootQueueIndex &b2) const {
102 if (boot == b2.boot) {
103 return index > b2.index;
104 }
105 return boot > b2.boot;
106 }
107};
108
Austin Schuh2dc8c7d2021-07-01 17:41:28 -0700109std::ostream &operator<<(std::ostream &os,
110 const struct BootTimestamp &timestamp);
Austin Schuh66168842021-08-17 19:42:21 -0700111std::ostream &operator<<(std::ostream &os, const struct BootDuration &duration);
Austin Schuh58646e22021-08-23 23:51:46 -0700112std::ostream &operator<<(std::ostream &os,
113 const struct BootQueueIndex &queue_index);
Austin Schuh2dc8c7d2021-07-01 17:41:28 -0700114
115inline bool BootTimestamp::operator<(const BootTimestamp &m2) const {
116 if (boot != m2.boot) {
117 return boot < m2.boot;
118 }
119
120 return time < m2.time;
121}
122inline bool BootTimestamp::operator<=(const BootTimestamp &m2) const {
123 if (boot != m2.boot) {
124 return boot <= m2.boot;
125 }
126
127 return time <= m2.time;
128}
129inline bool BootTimestamp::operator>=(const BootTimestamp &m2) const {
130 if (boot != m2.boot) {
131 return boot >= m2.boot;
132 }
133
134 return time >= m2.time;
135}
136inline bool BootTimestamp::operator>(const BootTimestamp &m2) const {
137 if (boot != m2.boot) {
138 return boot > m2.boot;
139 }
140
141 return time > m2.time;
142}
143
144inline bool BootTimestamp::operator==(const BootTimestamp &m2) const {
145 return boot == m2.boot && time == m2.time;
146}
147inline bool BootTimestamp::operator!=(const BootTimestamp &m2) const {
148 return boot != m2.boot || time != m2.time;
149}
150
151} // namespace aos::logger
152
153#endif // AOS_EVENTS_LOGGING_BOOT_TIMESTAMP_H_