• 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 #define LOG_TIME_SEC(t) ((t)->tv_sec)
28 /* next power of two after NS_PER_SEC */
29 #define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2))
30 
31 #ifdef __cplusplus
32 
33 extern "C" {
34 
35 struct log_time {
36  public:
37   uint32_t tv_sec = 0; /* good to Feb 5 2106 */
38   uint32_t tv_nsec = 0;
39 
40   static const uint32_t tv_sec_max = 0xFFFFFFFFUL;
41   static const uint32_t tv_nsec_max = 999999999UL;
42   static const timespec EPOCH;
43 
log_timelog_time44   log_time() {}
log_timelog_time45   explicit log_time(const timespec& T)
46       : tv_sec(static_cast<uint32_t>(T.tv_sec)), tv_nsec(static_cast<uint32_t>(T.tv_nsec)) {}
47   explicit log_time(uint32_t sec, uint32_t nsec = 0)
tv_seclog_time48       : tv_sec(sec), tv_nsec(nsec) {
49   }
50 #ifdef __linux__
log_timelog_time51   explicit log_time(clockid_t id) {
52     timespec T;
53     clock_gettime(id, &T);
54     tv_sec = static_cast<uint32_t>(T.tv_sec);
55     tv_nsec = static_cast<uint32_t>(T.tv_nsec);
56   }
57 #endif
log_timelog_time58   explicit log_time(const char* T) {
59     const uint8_t* c = reinterpret_cast<const uint8_t*>(T);
60     tv_sec = c[0] | (static_cast<uint32_t>(c[1]) << 8) |
61              (static_cast<uint32_t>(c[2]) << 16) |
62              (static_cast<uint32_t>(c[3]) << 24);
63     tv_nsec = c[4] | (static_cast<uint32_t>(c[5]) << 8) |
64               (static_cast<uint32_t>(c[6]) << 16) |
65               (static_cast<uint32_t>(c[7]) << 24);
66   }
67 
68   /* timespec */
69   bool operator==(const timespec& T) const {
70     return (tv_sec == static_cast<uint32_t>(T.tv_sec)) &&
71            (tv_nsec == static_cast<uint32_t>(T.tv_nsec));
72   }
73   bool operator!=(const timespec& T) const {
74     return !(*this == T);
75   }
76   bool operator<(const timespec& T) const {
77     return (tv_sec < static_cast<uint32_t>(T.tv_sec)) ||
78            ((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 
93   log_time operator-=(const timespec& T);
94   log_time operator-(const timespec& T) const {
95     log_time local(*this);
96     return local -= T;
97   }
98   log_time operator+=(const timespec& T);
99   log_time operator+(const timespec& T) const {
100     log_time local(*this);
101     return local += T;
102   }
103 
104   /* log_time */
105   bool operator==(const log_time& T) const {
106     return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec);
107   }
108   bool operator!=(const log_time& T) const {
109     return !(*this == T);
110   }
111   bool operator<(const log_time& T) const {
112     return (tv_sec < T.tv_sec) ||
113            ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec));
114   }
115   bool operator>=(const log_time& T) const {
116     return !(*this < T);
117   }
118   bool operator>(const log_time& T) const {
119     return (tv_sec > T.tv_sec) ||
120            ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec));
121   }
122   bool operator<=(const log_time& T) const {
123     return !(*this > T);
124   }
125 
126   log_time operator-=(const log_time& T);
127   log_time operator-(const log_time& T) const {
128     log_time local(*this);
129     return local -= T;
130   }
131   log_time operator+=(const log_time& T);
132   log_time operator+(const log_time& T) const {
133     log_time local(*this);
134     return local += T;
135   }
136 
nseclog_time137   uint64_t nsec() const {
138     return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec;
139   }
useclog_time140   uint64_t usec() const {
141     return static_cast<uint64_t>(tv_sec) * US_PER_SEC +
142            tv_nsec / (NS_PER_SEC / US_PER_SEC);
143   }
mseclog_time144   uint64_t msec() const {
145     return static_cast<uint64_t>(tv_sec) * MS_PER_SEC +
146            tv_nsec / (NS_PER_SEC / MS_PER_SEC);
147   }
148 
149   static const char default_format[];
150 
151   /* Add %#q for the fraction of a second to the standard library functions */
152   char* strptime(const char* s, const char* format = default_format);
153 } __attribute__((__packed__));
154 }
155 
156 #else /* __cplusplus */
157 
158 typedef struct log_time {
159   uint32_t tv_sec;
160   uint32_t tv_nsec;
161 } __attribute__((__packed__)) log_time;
162 
163 #endif /* __cplusplus */
164