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