xref: /aosp_15_r20/system/logging/liblog/include/log/log_time.h (revision 598139dc91b21518d67c408eaea2644226490971)
1*598139dcSAndroid Build Coastguard Worker /*
2*598139dcSAndroid Build Coastguard Worker  * Copyright (C) 2005-2017 The Android Open Source Project
3*598139dcSAndroid Build Coastguard Worker  *
4*598139dcSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*598139dcSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*598139dcSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*598139dcSAndroid Build Coastguard Worker  *
8*598139dcSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*598139dcSAndroid Build Coastguard Worker  *
10*598139dcSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*598139dcSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*598139dcSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*598139dcSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*598139dcSAndroid Build Coastguard Worker  * limitations under the License.
15*598139dcSAndroid Build Coastguard Worker  */
16*598139dcSAndroid Build Coastguard Worker 
17*598139dcSAndroid Build Coastguard Worker #pragma once
18*598139dcSAndroid Build Coastguard Worker 
19*598139dcSAndroid Build Coastguard Worker #include <stdint.h>
20*598139dcSAndroid Build Coastguard Worker #include <time.h>
21*598139dcSAndroid Build Coastguard Worker 
22*598139dcSAndroid Build Coastguard Worker /* struct log_time is a wire-format variant of struct timespec */
23*598139dcSAndroid Build Coastguard Worker #define NS_PER_SEC 1000000000ULL
24*598139dcSAndroid Build Coastguard Worker #define US_PER_SEC 1000000ULL
25*598139dcSAndroid Build Coastguard Worker #define MS_PER_SEC 1000ULL
26*598139dcSAndroid Build Coastguard Worker 
27*598139dcSAndroid Build Coastguard Worker #define LOG_TIME_SEC(t) ((t)->tv_sec)
28*598139dcSAndroid Build Coastguard Worker /* next power of two after NS_PER_SEC */
29*598139dcSAndroid Build Coastguard Worker #define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2))
30*598139dcSAndroid Build Coastguard Worker 
31*598139dcSAndroid Build Coastguard Worker #ifdef __cplusplus
32*598139dcSAndroid Build Coastguard Worker 
33*598139dcSAndroid Build Coastguard Worker extern "C" {
34*598139dcSAndroid Build Coastguard Worker 
35*598139dcSAndroid Build Coastguard Worker struct log_time {
36*598139dcSAndroid Build Coastguard Worker  public:
37*598139dcSAndroid Build Coastguard Worker   uint32_t tv_sec = 0; /* good to Feb 5 2106 */
38*598139dcSAndroid Build Coastguard Worker   uint32_t tv_nsec = 0;
39*598139dcSAndroid Build Coastguard Worker 
40*598139dcSAndroid Build Coastguard Worker   static constexpr timespec EPOCH = {0, 0};
41*598139dcSAndroid Build Coastguard Worker 
log_timelog_time42*598139dcSAndroid Build Coastguard Worker   log_time() {}
log_timelog_time43*598139dcSAndroid Build Coastguard Worker   explicit log_time(const timespec& T)
44*598139dcSAndroid Build Coastguard Worker       : tv_sec(static_cast<uint32_t>(T.tv_sec)), tv_nsec(static_cast<uint32_t>(T.tv_nsec)) {}
45*598139dcSAndroid Build Coastguard Worker   explicit log_time(uint32_t sec, uint32_t nsec = 0)
tv_seclog_time46*598139dcSAndroid Build Coastguard Worker       : tv_sec(sec), tv_nsec(nsec) {
47*598139dcSAndroid Build Coastguard Worker   }
48*598139dcSAndroid Build Coastguard Worker #ifdef __linux__
log_timelog_time49*598139dcSAndroid Build Coastguard Worker   explicit log_time(clockid_t id) {
50*598139dcSAndroid Build Coastguard Worker     timespec T;
51*598139dcSAndroid Build Coastguard Worker     clock_gettime(id, &T);
52*598139dcSAndroid Build Coastguard Worker     tv_sec = static_cast<uint32_t>(T.tv_sec);
53*598139dcSAndroid Build Coastguard Worker     tv_nsec = static_cast<uint32_t>(T.tv_nsec);
54*598139dcSAndroid Build Coastguard Worker   }
55*598139dcSAndroid Build Coastguard Worker #endif
56*598139dcSAndroid Build Coastguard Worker   /* timespec */
57*598139dcSAndroid Build Coastguard Worker   bool operator==(const timespec& T) const {
58*598139dcSAndroid Build Coastguard Worker     return (tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
59*598139dcSAndroid Build Coastguard Worker            (tv_nsec == static_cast<uint32_t>(T.tv_nsec));
60*598139dcSAndroid Build Coastguard Worker   }
61*598139dcSAndroid Build Coastguard Worker   bool operator!=(const timespec& T) const {
62*598139dcSAndroid Build Coastguard Worker     return !(*this == T);
63*598139dcSAndroid Build Coastguard Worker   }
64*598139dcSAndroid Build Coastguard Worker   bool operator<(const timespec& T) const {
65*598139dcSAndroid Build Coastguard Worker     return (tv_sec < static_cast<uint32_t>(T.tv_sec)) ||
66*598139dcSAndroid Build Coastguard Worker            ((tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
67*598139dcSAndroid Build Coastguard Worker             (tv_nsec < static_cast<uint32_t>(T.tv_nsec)));
68*598139dcSAndroid Build Coastguard Worker   }
69*598139dcSAndroid Build Coastguard Worker   bool operator>=(const timespec& T) const {
70*598139dcSAndroid Build Coastguard Worker     return !(*this < T);
71*598139dcSAndroid Build Coastguard Worker   }
72*598139dcSAndroid Build Coastguard Worker   bool operator>(const timespec& T) const {
73*598139dcSAndroid Build Coastguard Worker     return (tv_sec > static_cast<uint32_t>(T.tv_sec)) ||
74*598139dcSAndroid Build Coastguard Worker            ((tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
75*598139dcSAndroid Build Coastguard Worker             (tv_nsec > static_cast<uint32_t>(T.tv_nsec)));
76*598139dcSAndroid Build Coastguard Worker   }
77*598139dcSAndroid Build Coastguard Worker   bool operator<=(const timespec& T) const {
78*598139dcSAndroid Build Coastguard Worker     return !(*this > T);
79*598139dcSAndroid Build Coastguard Worker   }
80*598139dcSAndroid Build Coastguard Worker 
81*598139dcSAndroid Build Coastguard Worker   /* log_time */
82*598139dcSAndroid Build Coastguard Worker   bool operator==(const log_time& T) const {
83*598139dcSAndroid Build Coastguard Worker     return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec);
84*598139dcSAndroid Build Coastguard Worker   }
85*598139dcSAndroid Build Coastguard Worker   bool operator!=(const log_time& T) const {
86*598139dcSAndroid Build Coastguard Worker     return !(*this == T);
87*598139dcSAndroid Build Coastguard Worker   }
88*598139dcSAndroid Build Coastguard Worker   bool operator<(const log_time& T) const {
89*598139dcSAndroid Build Coastguard Worker     return (tv_sec < T.tv_sec) ||
90*598139dcSAndroid Build Coastguard Worker            ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec));
91*598139dcSAndroid Build Coastguard Worker   }
92*598139dcSAndroid Build Coastguard Worker   bool operator>=(const log_time& T) const {
93*598139dcSAndroid Build Coastguard Worker     return !(*this < T);
94*598139dcSAndroid Build Coastguard Worker   }
95*598139dcSAndroid Build Coastguard Worker   bool operator>(const log_time& T) const {
96*598139dcSAndroid Build Coastguard Worker     return (tv_sec > T.tv_sec) ||
97*598139dcSAndroid Build Coastguard Worker            ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec));
98*598139dcSAndroid Build Coastguard Worker   }
99*598139dcSAndroid Build Coastguard Worker   bool operator<=(const log_time& T) const {
100*598139dcSAndroid Build Coastguard Worker     return !(*this > T);
101*598139dcSAndroid Build Coastguard Worker   }
102*598139dcSAndroid Build Coastguard Worker 
103*598139dcSAndroid Build Coastguard Worker   log_time operator-=(const log_time& T) {
104*598139dcSAndroid Build Coastguard Worker     // No concept of negative time, clamp to EPOCH
105*598139dcSAndroid Build Coastguard Worker     if (*this <= T) {
106*598139dcSAndroid Build Coastguard Worker       return *this = log_time(EPOCH);
107*598139dcSAndroid Build Coastguard Worker     }
108*598139dcSAndroid Build Coastguard Worker 
109*598139dcSAndroid Build Coastguard Worker     if (this->tv_nsec < T.tv_nsec) {
110*598139dcSAndroid Build Coastguard Worker       --this->tv_sec;
111*598139dcSAndroid Build Coastguard Worker       this->tv_nsec = NS_PER_SEC + this->tv_nsec - T.tv_nsec;
112*598139dcSAndroid Build Coastguard Worker     } else {
113*598139dcSAndroid Build Coastguard Worker       this->tv_nsec -= T.tv_nsec;
114*598139dcSAndroid Build Coastguard Worker     }
115*598139dcSAndroid Build Coastguard Worker     this->tv_sec -= T.tv_sec;
116*598139dcSAndroid Build Coastguard Worker 
117*598139dcSAndroid Build Coastguard Worker     return *this;
118*598139dcSAndroid Build Coastguard Worker   }
119*598139dcSAndroid Build Coastguard Worker   log_time operator-(const log_time& T) const {
120*598139dcSAndroid Build Coastguard Worker     log_time local(*this);
121*598139dcSAndroid Build Coastguard Worker     return local -= T;
122*598139dcSAndroid Build Coastguard Worker   }
123*598139dcSAndroid Build Coastguard Worker   log_time operator+=(const log_time& T) {
124*598139dcSAndroid Build Coastguard Worker     this->tv_nsec += T.tv_nsec;
125*598139dcSAndroid Build Coastguard Worker     if (this->tv_nsec >= NS_PER_SEC) {
126*598139dcSAndroid Build Coastguard Worker       this->tv_nsec -= NS_PER_SEC;
127*598139dcSAndroid Build Coastguard Worker       ++this->tv_sec;
128*598139dcSAndroid Build Coastguard Worker     }
129*598139dcSAndroid Build Coastguard Worker     this->tv_sec += T.tv_sec;
130*598139dcSAndroid Build Coastguard Worker 
131*598139dcSAndroid Build Coastguard Worker     return *this;
132*598139dcSAndroid Build Coastguard Worker   }
133*598139dcSAndroid Build Coastguard Worker   log_time operator+(const log_time& T) const {
134*598139dcSAndroid Build Coastguard Worker     log_time local(*this);
135*598139dcSAndroid Build Coastguard Worker     return local += T;
136*598139dcSAndroid Build Coastguard Worker   }
137*598139dcSAndroid Build Coastguard Worker 
nseclog_time138*598139dcSAndroid Build Coastguard Worker   uint64_t nsec() const {
139*598139dcSAndroid Build Coastguard Worker     return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec;
140*598139dcSAndroid Build Coastguard Worker   }
useclog_time141*598139dcSAndroid Build Coastguard Worker   uint64_t usec() const {
142*598139dcSAndroid Build Coastguard Worker     return static_cast<uint64_t>(tv_sec) * US_PER_SEC +
143*598139dcSAndroid Build Coastguard Worker            tv_nsec / (NS_PER_SEC / US_PER_SEC);
144*598139dcSAndroid Build Coastguard Worker   }
mseclog_time145*598139dcSAndroid Build Coastguard Worker   uint64_t msec() const {
146*598139dcSAndroid Build Coastguard Worker     return static_cast<uint64_t>(tv_sec) * MS_PER_SEC +
147*598139dcSAndroid Build Coastguard Worker            tv_nsec / (NS_PER_SEC / MS_PER_SEC);
148*598139dcSAndroid Build Coastguard Worker   }
149*598139dcSAndroid Build Coastguard Worker 
150*598139dcSAndroid Build Coastguard Worker   /* Add %#q for the fraction of a second to the standard library functions */
151*598139dcSAndroid Build Coastguard Worker   char* strptime(const char* s, const char* format);
152*598139dcSAndroid Build Coastguard Worker } __attribute__((__packed__));
153*598139dcSAndroid Build Coastguard Worker }
154*598139dcSAndroid Build Coastguard Worker 
155*598139dcSAndroid Build Coastguard Worker #else /* __cplusplus */
156*598139dcSAndroid Build Coastguard Worker 
157*598139dcSAndroid Build Coastguard Worker typedef struct log_time {
158*598139dcSAndroid Build Coastguard Worker   uint32_t tv_sec;
159*598139dcSAndroid Build Coastguard Worker   uint32_t tv_nsec;
160*598139dcSAndroid Build Coastguard Worker } __attribute__((__packed__)) log_time;
161*598139dcSAndroid Build Coastguard Worker 
162*598139dcSAndroid Build Coastguard Worker #endif /* __cplusplus */
163