• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #pragma once
18 
19 #include <stdint.h>
20 #include <time.h>
21 
22 /* struct log_time is a wire-format variant of struct timespec */
23 #define NS_PER_SEC 1000000000ULL
24 #define US_PER_SEC 1000000ULL
25 #define MS_PER_SEC 1000ULL
26 
27 #ifndef __struct_log_time_defined
28 #define __struct_log_time_defined
29 
30 #define LOG_TIME_SEC(t) ((t)->tv_sec)
31 /* next power of two after NS_PER_SEC */
32 #define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2))
33 
34 #ifdef __cplusplus
35 
36 extern "C" {
37 
38 /*
39  * NB: we did NOT define a copy constructor. This will result in structure
40  * no longer being compatible with pass-by-value which is desired
41  * efficient behavior. Also, pass-by-reference breaks C/C++ ABI.
42  */
43 struct log_time {
44  public:
45   uint32_t tv_sec = 0; /* good to Feb 5 2106 */
46   uint32_t tv_nsec = 0;
47 
48   static const uint32_t tv_sec_max = 0xFFFFFFFFUL;
49   static const uint32_t tv_nsec_max = 999999999UL;
50   static const timespec EPOCH;
51 
log_timelog_time52   log_time() {}
log_timelog_time53   explicit log_time(const timespec& T)
54       : tv_sec(static_cast<uint32_t>(T.tv_sec)), tv_nsec(static_cast<uint32_t>(T.tv_nsec)) {}
55   explicit log_time(uint32_t sec, uint32_t nsec = 0)
tv_seclog_time56       : tv_sec(sec), tv_nsec(nsec) {
57   }
58 #ifdef __linux__
log_timelog_time59   explicit log_time(clockid_t id) {
60     timespec T;
61     clock_gettime(id, &T);
62     tv_sec = static_cast<uint32_t>(T.tv_sec);
63     tv_nsec = static_cast<uint32_t>(T.tv_nsec);
64   }
65 #endif
log_timelog_time66   explicit log_time(const char* T) {
67     const uint8_t* c = reinterpret_cast<const uint8_t*>(T);
68     tv_sec = c[0] | (static_cast<uint32_t>(c[1]) << 8) |
69              (static_cast<uint32_t>(c[2]) << 16) |
70              (static_cast<uint32_t>(c[3]) << 24);
71     tv_nsec = c[4] | (static_cast<uint32_t>(c[5]) << 8) |
72               (static_cast<uint32_t>(c[6]) << 16) |
73               (static_cast<uint32_t>(c[7]) << 24);
74   }
75 
76   /* timespec */
77   bool operator==(const timespec& T) const {
78     return (tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
79            (tv_nsec == static_cast<uint32_t>(T.tv_nsec));
80   }
81   bool operator!=(const timespec& T) const {
82     return !(*this == T);
83   }
84   bool operator<(const timespec& T) const {
85     return (tv_sec < static_cast<uint32_t>(T.tv_sec)) ||
86            ((tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
87             (tv_nsec < static_cast<uint32_t>(T.tv_nsec)));
88   }
89   bool operator>=(const timespec& T) const {
90     return !(*this < T);
91   }
92   bool operator>(const timespec& T) const {
93     return (tv_sec > static_cast<uint32_t>(T.tv_sec)) ||
94            ((tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
95             (tv_nsec > static_cast<uint32_t>(T.tv_nsec)));
96   }
97   bool operator<=(const timespec& T) const {
98     return !(*this > T);
99   }
100 
101   log_time operator-=(const timespec& T);
102   log_time operator-(const timespec& T) const {
103     log_time local(*this);
104     return local -= T;
105   }
106   log_time operator+=(const timespec& T);
107   log_time operator+(const timespec& T) const {
108     log_time local(*this);
109     return local += T;
110   }
111 
112   /* log_time */
113   bool operator==(const log_time& T) const {
114     return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec);
115   }
116   bool operator!=(const log_time& T) const {
117     return !(*this == T);
118   }
119   bool operator<(const log_time& T) const {
120     return (tv_sec < T.tv_sec) ||
121            ((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 
134   log_time operator-=(const log_time& T);
135   log_time operator-(const log_time& T) const {
136     log_time local(*this);
137     return local -= T;
138   }
139   log_time operator+=(const log_time& T);
140   log_time operator+(const log_time& T) const {
141     log_time local(*this);
142     return local += T;
143   }
144 
nseclog_time145   uint64_t nsec() const {
146     return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec;
147   }
useclog_time148   uint64_t usec() const {
149     return static_cast<uint64_t>(tv_sec) * US_PER_SEC +
150            tv_nsec / (NS_PER_SEC / US_PER_SEC);
151   }
mseclog_time152   uint64_t msec() const {
153     return static_cast<uint64_t>(tv_sec) * MS_PER_SEC +
154            tv_nsec / (NS_PER_SEC / MS_PER_SEC);
155   }
156 
157   static const char default_format[];
158 
159   /* Add %#q for the fraction of a second to the standard library functions */
160   char* strptime(const char* s, const char* format = default_format);
161 } __attribute__((__packed__));
162 }
163 
164 #else /* __cplusplus */
165 
166 typedef struct log_time {
167   uint32_t tv_sec;
168   uint32_t tv_nsec;
169 } __attribute__((__packed__)) log_time;
170 
171 #endif /* __cplusplus */
172 
173 #endif /* __struct_log_time_defined */
174