1 /*
2  * Copyright (C) 2005-2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _LIBS_LOG_LOG_TIME_H
18 #define _LIBS_LOG_LOG_TIME_H
19 
20 #include <stdint.h>
21 #include <time.h>
22 
23 /* struct log_time is a wire-format variant of struct timespec */
24 #define NS_PER_SEC 1000000000ULL
25 #define US_PER_SEC 1000000ULL
26 #define MS_PER_SEC 1000ULL
27 
28 #ifndef __struct_log_time_defined
29 #define __struct_log_time_defined
30 
31 #define LOG_TIME_SEC(t) ((t)->tv_sec)
32 /* next power of two after NS_PER_SEC */
33 #define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2))
34 
35 #ifdef __cplusplus
36 
37 /*
38  * NB: we did NOT define a copy constructor. This will result in structure
39  * no longer being compatible with pass-by-value which is desired
40  * efficient behavior. Also, pass-by-reference breaks C/C++ ABI.
41  */
42 struct log_time {
43  public:
44   uint32_t tv_sec; /* good to Feb 5 2106 */
45   uint32_t tv_nsec;
46 
47   static const uint32_t tv_sec_max = 0xFFFFFFFFUL;
48   static const uint32_t tv_nsec_max = 999999999UL;
49 
log_timelog_time50   log_time(const timespec& T)
51       : tv_sec(static_cast<uint32_t>(T.tv_sec)),
52         tv_nsec(static_cast<uint32_t>(T.tv_nsec)) {
53   }
54   explicit log_time(uint32_t sec, uint32_t nsec = 0)
tv_seclog_time55       : tv_sec(sec), tv_nsec(nsec) {
56   }
57 #ifdef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_
58 #define __struct_log_time_private_defined
59   static const timespec EPOCH;
60 #endif
log_timelog_time61   log_time() {
62   }
63 #ifdef __linux__
log_timelog_time64   explicit log_time(clockid_t id) {
65     timespec T;
66     clock_gettime(id, &T);
67     tv_sec = static_cast<uint32_t>(T.tv_sec);
68     tv_nsec = static_cast<uint32_t>(T.tv_nsec);
69   }
70 #endif
log_timelog_time71   explicit log_time(const char* T) {
72     const uint8_t* c = reinterpret_cast<const uint8_t*>(T);
73     tv_sec = c[0] | (static_cast<uint32_t>(c[1]) << 8) |
74              (static_cast<uint32_t>(c[2]) << 16) |
75              (static_cast<uint32_t>(c[3]) << 24);
76     tv_nsec = c[4] | (static_cast<uint32_t>(c[5]) << 8) |
77               (static_cast<uint32_t>(c[6]) << 16) |
78               (static_cast<uint32_t>(c[7]) << 24);
79   }
80 
81   /* timespec */
82   bool operator==(const timespec& T) const {
83     return (tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
84            (tv_nsec == static_cast<uint32_t>(T.tv_nsec));
85   }
86   bool operator!=(const timespec& T) const {
87     return !(*this == T);
88   }
89   bool operator<(const timespec& T) const {
90     return (tv_sec < static_cast<uint32_t>(T.tv_sec)) ||
91            ((tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
92             (tv_nsec < static_cast<uint32_t>(T.tv_nsec)));
93   }
94   bool operator>=(const timespec& T) const {
95     return !(*this < T);
96   }
97   bool operator>(const timespec& T) const {
98     return (tv_sec > static_cast<uint32_t>(T.tv_sec)) ||
99            ((tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
100             (tv_nsec > static_cast<uint32_t>(T.tv_nsec)));
101   }
102   bool operator<=(const timespec& T) const {
103     return !(*this > T);
104   }
105 
106 #ifdef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_
107   log_time operator-=(const timespec& T);
108   log_time operator-(const timespec& T) const {
109     log_time local(*this);
110     return local -= T;
111   }
112   log_time operator+=(const timespec& T);
113   log_time operator+(const timespec& T) const {
114     log_time local(*this);
115     return local += T;
116   }
117 #endif
118 
119   /* log_time */
120   bool operator==(const log_time& T) const {
121     return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec);
122   }
123   bool operator!=(const log_time& T) const {
124     return !(*this == T);
125   }
126   bool operator<(const log_time& T) const {
127     return (tv_sec < T.tv_sec) ||
128            ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec));
129   }
130   bool operator>=(const log_time& T) const {
131     return !(*this < T);
132   }
133   bool operator>(const log_time& T) const {
134     return (tv_sec > T.tv_sec) ||
135            ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec));
136   }
137   bool operator<=(const log_time& T) const {
138     return !(*this > T);
139   }
140 
141 #ifdef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_
142   log_time operator-=(const log_time& T);
143   log_time operator-(const log_time& T) const {
144     log_time local(*this);
145     return local -= T;
146   }
147   log_time operator+=(const log_time& T);
148   log_time operator+(const log_time& T) const {
149     log_time local(*this);
150     return local += T;
151   }
152 #endif
153 
nseclog_time154   uint64_t nsec() const {
155     return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec;
156   }
useclog_time157   uint64_t usec() const {
158     return static_cast<uint64_t>(tv_sec) * US_PER_SEC +
159            tv_nsec / (NS_PER_SEC / US_PER_SEC);
160   }
mseclog_time161   uint64_t msec() const {
162     return static_cast<uint64_t>(tv_sec) * MS_PER_SEC +
163            tv_nsec / (NS_PER_SEC / MS_PER_SEC);
164   }
165 
166 #ifdef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_LOGGER_H_
167   static const char default_format[];
168 
169   /* Add %#q for the fraction of a second to the standard library functions */
170   char* strptime(const char* s, const char* format = default_format);
171 #endif
172 } __attribute__((__packed__));
173 
174 #else /* __cplusplus */
175 
176 typedef struct log_time {
177   uint32_t tv_sec;
178   uint32_t tv_nsec;
179 } __attribute__((__packed__)) log_time;
180 
181 #endif /* __cplusplus */
182 
183 #endif /* __struct_log_time_defined */
184 
185 #endif /* _LIBS_LOG_LOG_TIME_H */
186