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